mirror of
https://github.com/MariaDB/server.git
synced 2025-02-02 12:01:42 +01:00
Merge kboortz@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into mysql.com:/Users/kent/mysql/bk/mysql-5.1-new mysql-test/r/sp.result: Auto merged sql/sp_head.cc: Auto merged sql/sql_class.h: Auto merged
This commit is contained in:
commit
031ec5d2bd
1049 changed files with 35918 additions and 168064 deletions
233
.bzrignore
233
.bzrignore
|
@ -133,137 +133,107 @@ autom4te.cache/*
|
||||||
autom4te.cache/output.0
|
autom4te.cache/output.0
|
||||||
autom4te.cache/requests
|
autom4te.cache/requests
|
||||||
autom4te.cache/traces.0
|
autom4te.cache/traces.0
|
||||||
bdb/*.ds?
|
storage/bdb/*.ds?
|
||||||
bdb/*.vcproj
|
storage/bdb/*.vcproj
|
||||||
bdb/README
|
storage/bdb/README
|
||||||
bdb/btree/btree_auto.c
|
storage/bdb/btree/btree_auto.c
|
||||||
bdb/build_unix/*
|
storage/bdb/build_unix/*
|
||||||
bdb/build_vxworks/db.h
|
storage/bdb/build_vxworks/db.h
|
||||||
bdb/build_vxworks/db_int.h
|
storage/bdb/build_vxworks/db_int.h
|
||||||
bdb/build_win32/db.h
|
storage/bdb/build_win32/db.h
|
||||||
bdb/build_win32/db_archive.dsp
|
storage/bdb/build_win32/db_archive.dsp
|
||||||
bdb/build_win32/db_checkpoint.dsp
|
storage/bdb/build_win32/db_checkpoint.dsp
|
||||||
bdb/build_win32/db_config.h
|
storage/bdb/build_win32/db_config.h
|
||||||
bdb/build_win32/db_cxx.h
|
storage/bdb/build_win32/db_cxx.h
|
||||||
bdb/build_win32/db_deadlock.dsp
|
storage/bdb/build_win32/db_deadlock.dsp
|
||||||
bdb/build_win32/db_dll.dsp
|
storage/bdb/build_win32/db_dll.dsp
|
||||||
bdb/build_win32/db_dump.dsp
|
storage/bdb/build_win32/db_dump.dsp
|
||||||
bdb/build_win32/db_int.h
|
storage/bdb/build_win32/db_int.h
|
||||||
bdb/build_win32/db_java.dsp
|
storage/bdb/build_win32/db_java.dsp
|
||||||
bdb/build_win32/db_load.dsp
|
storage/bdb/build_win32/db_load.dsp
|
||||||
bdb/build_win32/db_perf.dsp
|
storage/bdb/build_win32/db_perf.dsp
|
||||||
bdb/build_win32/db_printlog.dsp
|
storage/bdb/build_win32/db_printlog.dsp
|
||||||
bdb/build_win32/db_recover.dsp
|
storage/bdb/build_win32/db_recover.dsp
|
||||||
bdb/build_win32/db_stat.dsp
|
storage/bdb/build_win32/db_stat.dsp
|
||||||
bdb/build_win32/db_static.dsp
|
storage/bdb/build_win32/db_static.dsp
|
||||||
bdb/build_win32/db_tcl.dsp
|
storage/bdb/build_win32/db_tcl.dsp
|
||||||
bdb/build_win32/db_test.dsp
|
storage/bdb/build_win32/db_test.dsp
|
||||||
bdb/build_win32/db_upgrade.dsp
|
storage/bdb/build_win32/db_upgrade.dsp
|
||||||
bdb/build_win32/db_verify.dsp
|
storage/bdb/build_win32/db_verify.dsp
|
||||||
bdb/build_win32/ex_access.dsp
|
storage/bdb/build_win32/ex_access.dsp
|
||||||
bdb/build_win32/ex_btrec.dsp
|
storage/bdb/build_win32/ex_btrec.dsp
|
||||||
bdb/build_win32/ex_env.dsp
|
storage/bdb/build_win32/ex_env.dsp
|
||||||
bdb/build_win32/ex_lock.dsp
|
storage/bdb/build_win32/ex_lock.dsp
|
||||||
bdb/build_win32/ex_mpool.dsp
|
storage/bdb/build_win32/ex_mpool.dsp
|
||||||
bdb/build_win32/ex_tpcb.dsp
|
storage/bdb/build_win32/ex_tpcb.dsp
|
||||||
bdb/build_win32/excxx_access.dsp
|
storage/bdb/build_win32/excxx_access.dsp
|
||||||
bdb/build_win32/excxx_btrec.dsp
|
storage/bdb/build_win32/excxx_btrec.dsp
|
||||||
bdb/build_win32/excxx_env.dsp
|
storage/bdb/build_win32/excxx_env.dsp
|
||||||
bdb/build_win32/excxx_lock.dsp
|
storage/bdb/build_win32/excxx_lock.dsp
|
||||||
bdb/build_win32/excxx_mpool.dsp
|
storage/bdb/build_win32/excxx_mpool.dsp
|
||||||
bdb/build_win32/excxx_tpcb.dsp
|
storage/bdb/build_win32/excxx_tpcb.dsp
|
||||||
bdb/build_win32/include.tcl
|
storage/bdb/build_win32/include.tcl
|
||||||
bdb/build_win32/libdb.def
|
storage/bdb/build_win32/libdb.def
|
||||||
bdb/build_win32/libdb.rc
|
storage/bdb/build_win32/libdb.rc
|
||||||
bdb/db/crdel_auto.c
|
storage/bdb/db/crdel_auto.c
|
||||||
bdb/db/db_auto.c
|
storage/bdb/db/db_auto.c
|
||||||
bdb/dbinc_auto/*.*
|
storage/bdb/dbinc_auto/*.*
|
||||||
bdb/dbreg/dbreg_auto.c
|
storage/bdb/dbreg/dbreg_auto.c
|
||||||
bdb/dist/autom4te-2.53.cache/*
|
storage/bdb/dist/autom4te-2.53.cache/*
|
||||||
bdb/dist/autom4te-2.53.cache/output.0
|
storage/bdb/dist/autom4te-2.53.cache/output.0
|
||||||
bdb/dist/autom4te-2.53.cache/requests
|
storage/bdb/dist/autom4te-2.53.cache/requests
|
||||||
bdb/dist/autom4te-2.53.cache/traces.0
|
storage/bdb/dist/autom4te-2.53.cache/traces.0
|
||||||
bdb/dist/autom4te.cache/*
|
storage/bdb/dist/autom4te.cache/*
|
||||||
bdb/dist/autom4te.cache/output.0
|
storage/bdb/dist/autom4te.cache/output.0
|
||||||
bdb/dist/autom4te.cache/requests
|
storage/bdb/dist/autom4te.cache/requests
|
||||||
bdb/dist/autom4te.cache/traces.0
|
storage/bdb/dist/autom4te.cache/traces.0
|
||||||
bdb/dist/config.hin
|
storage/bdb/dist/config.hin
|
||||||
bdb/dist/configure
|
storage/bdb/dist/configure
|
||||||
bdb/dist/tags
|
storage/bdb/dist/tags
|
||||||
bdb/dist/template/db_server_proc
|
storage/bdb/dist/template/db_server_proc
|
||||||
bdb/dist/template/gen_client_ret
|
storage/bdb/dist/template/gen_client_ret
|
||||||
bdb/dist/template/rec_btree
|
storage/bdb/dist/template/rec_btree
|
||||||
bdb/dist/template/rec_crdel
|
storage/bdb/dist/template/rec_crdel
|
||||||
bdb/dist/template/rec_db
|
storage/bdb/dist/template/rec_db
|
||||||
bdb/dist/template/rec_dbreg
|
storage/bdb/dist/template/rec_dbreg
|
||||||
bdb/dist/template/rec_fileops
|
storage/bdb/dist/template/rec_fileops
|
||||||
bdb/dist/template/rec_hash
|
storage/bdb/dist/template/rec_hash
|
||||||
bdb/dist/template/rec_log
|
storage/bdb/dist/template/rec_log
|
||||||
bdb/dist/template/rec_qam
|
storage/bdb/dist/template/rec_qam
|
||||||
bdb/dist/template/rec_txn
|
storage/bdb/dist/template/rec_txn
|
||||||
bdb/examples_c/ex_apprec/ex_apprec_auto.c
|
storage/bdb/fileops/fileops_auto.c
|
||||||
bdb/examples_c/ex_apprec/ex_apprec_auto.h
|
storage/bdb/hash/hash_auto.c
|
||||||
bdb/examples_c/ex_apprec/ex_apprec_template
|
storage/bdb/include/btree_auto.h
|
||||||
bdb/examples_java
|
storage/bdb/include/btree_ext.h
|
||||||
bdb/fileops/fileops_auto.c
|
storage/bdb/include/clib_ext.h
|
||||||
bdb/hash/hash_auto.c
|
storage/bdb/include/common_ext.h
|
||||||
bdb/include/btree_auto.h
|
storage/bdb/include/crdel_auto.h
|
||||||
bdb/include/btree_ext.h
|
storage/bdb/include/db_auto.h
|
||||||
bdb/include/clib_ext.h
|
storage/bdb/include/db_ext.h
|
||||||
bdb/include/common_ext.h
|
storage/bdb/include/db_server.h
|
||||||
bdb/include/crdel_auto.h
|
storage/bdb/include/env_ext.h
|
||||||
bdb/include/db_auto.h
|
storage/bdb/include/gen_client_ext.h
|
||||||
bdb/include/db_ext.h
|
storage/bdb/include/gen_server_ext.h
|
||||||
bdb/include/db_server.h
|
storage/bdb/include/hash_auto.h
|
||||||
bdb/include/env_ext.h
|
storage/bdb/include/hash_ext.h
|
||||||
bdb/include/gen_client_ext.h
|
storage/bdb/include/lock_ext.h
|
||||||
bdb/include/gen_server_ext.h
|
storage/bdb/include/log_auto.h
|
||||||
bdb/include/hash_auto.h
|
storage/bdb/include/log_ext.h
|
||||||
bdb/include/hash_ext.h
|
storage/bdb/include/mp_ext.h
|
||||||
bdb/include/lock_ext.h
|
storage/bdb/include/mutex_ext.h
|
||||||
bdb/include/log_auto.h
|
storage/bdb/include/os_ext.h
|
||||||
bdb/include/log_ext.h
|
storage/bdb/include/qam_auto.h
|
||||||
bdb/include/mp_ext.h
|
storage/bdb/include/qam_ext.h
|
||||||
bdb/include/mutex_ext.h
|
storage/bdb/include/rpc_client_ext.h
|
||||||
bdb/include/os_ext.h
|
storage/bdb/include/rpc_server_ext.h
|
||||||
bdb/include/qam_auto.h
|
storage/bdb/include/tcl_ext.h
|
||||||
bdb/include/qam_ext.h
|
storage/bdb/include/txn_auto.h
|
||||||
bdb/include/rpc_client_ext.h
|
storage/bdb/include/txn_ext.h
|
||||||
bdb/include/rpc_server_ext.h
|
storage/bdb/include/xa_ext.h
|
||||||
bdb/include/tcl_ext.h
|
storage/bdb/log/log_auto.c
|
||||||
bdb/include/txn_auto.h
|
storage/bdb/qam/qam_auto.c
|
||||||
bdb/include/txn_ext.h
|
storage/bdb/txn/txn_auto.c
|
||||||
bdb/include/xa_ext.h
|
storage/bdb/txn/txn_autop.c
|
||||||
bdb/java/src/com/sleepycat/db/Db.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbBtreeStat.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbConstants.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbHashStat.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbLockStat.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbLogStat.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbMpoolFStat.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbQueueStat.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbRepStat.java
|
|
||||||
bdb/java/src/com/sleepycat/db/DbTxnStat.java
|
|
||||||
bdb/libdb_java/java_stat_auto.c
|
|
||||||
bdb/libdb_java/java_stat_auto.h
|
|
||||||
bdb/log/log_auto.c
|
|
||||||
bdb/qam/qam_auto.c
|
|
||||||
bdb/rpc_client/db_server_clnt.c
|
|
||||||
bdb/rpc_client/gen_client.c
|
|
||||||
bdb/rpc_server/c/db_server_proc.c
|
|
||||||
bdb/rpc_server/c/db_server_proc.sed
|
|
||||||
bdb/rpc_server/c/db_server_svc.c
|
|
||||||
bdb/rpc_server/c/db_server_xdr.c
|
|
||||||
bdb/rpc_server/c/gen_db_server.c
|
|
||||||
bdb/rpc_server/db_server.x
|
|
||||||
bdb/rpc_server/db_server_proc.sed
|
|
||||||
bdb/rpc_server/db_server_svc.c
|
|
||||||
bdb/rpc_server/db_server_xdr.c
|
|
||||||
bdb/rpc_server/gen_db_server.c
|
|
||||||
bdb/test/TESTS
|
|
||||||
bdb/test/include.tcl
|
|
||||||
bdb/test/logtrack.list
|
|
||||||
bdb/txn/txn_auto.c
|
|
||||||
binary/*
|
binary/*
|
||||||
bkpull.log
|
bkpull.log
|
||||||
bkpull.log*
|
bkpull.log*
|
||||||
|
@ -1688,3 +1658,4 @@ vio/viotest-sslconnect.cpp
|
||||||
vio/viotest.cpp
|
vio/viotest.cpp
|
||||||
zlib/*.ds?
|
zlib/*.ds?
|
||||||
zlib/*.vcproj
|
zlib/*.vcproj
|
||||||
|
client/mysqlslap
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#shift
|
#shift
|
||||||
FROM=$USER@mysql.com
|
FROM=$USER@mysql.com
|
||||||
INTERNALS=internals@lists.mysql.com
|
COMMITS=commits@lists.mysql.com
|
||||||
DOCS=docs-commit@mysql.com
|
DOCS=docs-commit@mysql.com
|
||||||
LIMIT=10000
|
LIMIT=10000
|
||||||
VERSION="5.1"
|
VERSION="5.1"
|
||||||
|
@ -61,14 +61,14 @@ EOF
|
||||||
) | /usr/sbin/sendmail -t
|
) | /usr/sbin/sendmail -t
|
||||||
|
|
||||||
#++
|
#++
|
||||||
# internals@ mail
|
# commits@ mail
|
||||||
#--
|
#--
|
||||||
echo "Notifying internals list at $INTERNALS"
|
echo "Notifying commits list at $COMMITS"
|
||||||
(
|
(
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
List-ID: <bk.mysql-$VERSION>
|
List-ID: <bk.mysql-$VERSION>
|
||||||
From: $FROM
|
From: $FROM
|
||||||
To: $INTERNALS
|
To: $COMMITS
|
||||||
Subject: bk commit into $VERSION tree ($CHANGESET)$BS
|
Subject: bk commit into $VERSION tree ($CHANGESET)$BS
|
||||||
X-CSetKey: <$CSETKEY>
|
X-CSetKey: <$CSETKEY>
|
||||||
$BH
|
$BH
|
||||||
|
|
|
@ -120,6 +120,28 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||||
|
<File
|
||||||
|
RelativePath="crypto\aes_method.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Max|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\btree\bt_compact.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="btree\bt_compare.c">
|
RelativePath="btree\bt_compare.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -500,6 +522,25 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="crypto\crypto.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Max|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="db\db.c">
|
RelativePath="db\db.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -595,6 +636,9 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\db_clock.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="db\db_conv.c">
|
RelativePath="db\db_conv.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -994,25 +1038,6 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="env\db_shash.c">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Max|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="db\db_setid.c">
|
RelativePath="db\db_setid.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -1051,6 +1076,25 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="env\db_shash.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Max|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="db\db_stati.c">
|
RelativePath="db\db_stati.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -1279,6 +1323,9 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\env\env_failchk.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="env\env_file.c">
|
RelativePath="env\env_file.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -1374,6 +1421,9 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\env\env_register.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="env\env_stat.c">
|
RelativePath="env\env_stat.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -1811,6 +1861,9 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lock\lock_failchk.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="lock\lock_id.c">
|
RelativePath="lock\lock_id.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -1831,7 +1884,7 @@
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="lock\lock_method.c">
|
RelativePath="lock\lock_list.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Max|Win32">
|
Name="Max|Win32">
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -1850,7 +1903,7 @@
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="lock\lock_list.c">
|
RelativePath="lock\lock_method.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Max|Win32">
|
Name="Max|Win32">
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -2001,6 +2054,9 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\log\log_debug.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="log\log_get.c">
|
RelativePath="log\log_get.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -2324,6 +2380,37 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="crypto\mersenne\mt19937db.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Max|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\mutex\mut_alloc.c">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\mutex\mut_method.c">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\mutex\mut_region.c">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\mutex\mut_stat.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="mutex\mut_tas.c">
|
RelativePath="mutex\mut_tas.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -2362,25 +2449,6 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="mutex\mutex.c">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Max|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="os_win32\os_abs.c">
|
RelativePath="os_win32\os_abs.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -2514,6 +2582,9 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\os_win32\os_flock.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="os_win32\os_fsync.c">
|
RelativePath="os_win32\os_fsync.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -3103,6 +3174,12 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\rep\rep_elect.c">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\rep\rep_log.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="rep\rep_method.c">
|
RelativePath="rep\rep_method.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -3179,6 +3256,9 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\rep\rep_stub.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="rep\rep_util.c">
|
RelativePath="rep\rep_util.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -3198,6 +3278,47 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\rep\rep_verify.c">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="crypto\rijndael\rijndael-alg-fst.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Max|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="crypto\rijndael\rijndael-api-fst.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Max|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="hmac\sha1.c">
|
RelativePath="hmac\sha1.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -3274,6 +3395,12 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\txn\txn_chkpt.c">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\txn\txn_failchk.c">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="txn\txn_method.c">
|
RelativePath="txn\txn_method.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -3483,101 +3610,6 @@
|
||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="crypto\aes_method.c">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Max|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="crypto\crypto.c">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Max|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="crypto\mersenne\mt19937db.c">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Max|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="crypto\rijndael\rijndael-api-fst.c">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Max|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="crypto\rijndael\rijndael-alg-fst.c">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Max|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions=""/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
|
|
|
@ -341,6 +341,7 @@ long SSL_CTX_sess_set_cache_size(SSL_CTX*, long);
|
||||||
long SSL_CTX_set_tmp_dh(SSL_CTX*, DH*);
|
long SSL_CTX_set_tmp_dh(SSL_CTX*, DH*);
|
||||||
|
|
||||||
void OpenSSL_add_all_algorithms(void);
|
void OpenSSL_add_all_algorithms(void);
|
||||||
|
void SSL_library_init();
|
||||||
void SSLeay_add_ssl_algorithms(void);
|
void SSLeay_add_ssl_algorithms(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -648,6 +648,10 @@ void OpenSSL_add_all_algorithms() // compatibility only
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
void SSL_library_init() // compatibility only
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
DH* DH_new(void)
|
DH* DH_new(void)
|
||||||
{
|
{
|
||||||
DH* dh = new (ys) DH;
|
DH* dh = new (ys) DH;
|
||||||
|
|
|
@ -117,6 +117,9 @@ typedef unsigned long long my_ulonglong;
|
||||||
|
|
||||||
#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
|
#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
|
||||||
|
|
||||||
|
/* backward compatibility define - to be removed eventually */
|
||||||
|
#define ER_WARN_DATA_TRUNCATED WARN_DATA_TRUNCATED
|
||||||
|
|
||||||
typedef struct st_mysql_rows {
|
typedef struct st_mysql_rows {
|
||||||
struct st_mysql_rows *next; /* list of rows */
|
struct st_mysql_rows *next; /* list of rows */
|
||||||
MYSQL_ROW data;
|
MYSQL_ROW data;
|
||||||
|
|
122
mysql-test/include/sp-vars.inc
Normal file
122
mysql-test/include/sp-vars.inc
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
delimiter |;
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE PROCEDURE sp_vars_check_dflt()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v1 TINYINT DEFAULT 1e200;
|
||||||
|
DECLARE v1u TINYINT UNSIGNED DEFAULT 1e200;
|
||||||
|
DECLARE v2 TINYINT DEFAULT -1e200;
|
||||||
|
DECLARE v2u TINYINT UNSIGNED DEFAULT -1e200;
|
||||||
|
DECLARE v3 TINYINT DEFAULT 300;
|
||||||
|
DECLARE v3u TINYINT UNSIGNED DEFAULT 300;
|
||||||
|
DECLARE v4 TINYINT DEFAULT -300;
|
||||||
|
DECLARE v4u TINYINT UNSIGNED DEFAULT -300;
|
||||||
|
|
||||||
|
DECLARE v5 TINYINT DEFAULT 10 * 10 * 10;
|
||||||
|
DECLARE v5u TINYINT UNSIGNED DEFAULT 10 * 10 * 10;
|
||||||
|
DECLARE v6 TINYINT DEFAULT -10 * 10 * 10;
|
||||||
|
DECLARE v6u TINYINT UNSIGNED DEFAULT -10 * 10 * 10;
|
||||||
|
|
||||||
|
DECLARE v7 TINYINT DEFAULT '10';
|
||||||
|
DECLARE v8 TINYINT DEFAULT '10 ';
|
||||||
|
DECLARE v9 TINYINT DEFAULT ' 10 ';
|
||||||
|
DECLARE v10 TINYINT DEFAULT 'String 10 ';
|
||||||
|
DECLARE v11 TINYINT DEFAULT 'String10';
|
||||||
|
DECLARE v12 TINYINT DEFAULT '10 String';
|
||||||
|
DECLARE v13 TINYINT DEFAULT '10String';
|
||||||
|
DECLARE v14 TINYINT DEFAULT concat('10', ' ');
|
||||||
|
DECLARE v15 TINYINT DEFAULT concat(' ', '10');
|
||||||
|
DECLARE v16 TINYINT DEFAULT concat('Hello, ', 'world');
|
||||||
|
|
||||||
|
DECLARE v17 DECIMAL(64, 2) DEFAULT 12;
|
||||||
|
DECLARE v18 DECIMAL(64, 2) DEFAULT 12.123;
|
||||||
|
DECLARE v19 DECIMAL(64, 2) DEFAULT 11 + 1;
|
||||||
|
DECLARE v20 DECIMAL(64, 2) DEFAULT 12 + 0.123;
|
||||||
|
|
||||||
|
SELECT v1, v1u, v2, v2u, v3, v3u, v4, v4u;
|
||||||
|
SELECT v5, v5u, v6, v6u;
|
||||||
|
SELECT v7, v8, v9, v10, v11, v12, v13, v14, v15, v16;
|
||||||
|
SELECT v17, v18, v19, v20;
|
||||||
|
END|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE PROCEDURE sp_vars_check_assignment()
|
||||||
|
BEGIN
|
||||||
|
DECLARE i1, i2, i3, i4 TINYINT;
|
||||||
|
DECLARE u1, u2, u3, u4 TINYINT UNSIGNED;
|
||||||
|
DECLARE d1, d2, d3 DECIMAL(64, 2);
|
||||||
|
|
||||||
|
SET i1 = 1e200;
|
||||||
|
SET i2 = -1e200;
|
||||||
|
SET i3 = 300;
|
||||||
|
SET i4 = -300;
|
||||||
|
|
||||||
|
SELECT i1, i2, i3, i4;
|
||||||
|
|
||||||
|
SET i1 = 10 * 10 * 10;
|
||||||
|
SET i2 = -10 * 10 * 10;
|
||||||
|
SET i3 = sign(10 * 10) * 10 * 20;
|
||||||
|
SET i4 = sign(-10 * 10) * -10 * 20;
|
||||||
|
|
||||||
|
SELECT i1, i2, i3, i4;
|
||||||
|
|
||||||
|
SET u1 = 1e200;
|
||||||
|
SET u2 = -1e200;
|
||||||
|
SET u3 = 300;
|
||||||
|
SET u4 = -300;
|
||||||
|
|
||||||
|
SELECT u1, u2, u3, u4;
|
||||||
|
|
||||||
|
SET u1 = 10 * 10 * 10;
|
||||||
|
SET u2 = -10 * 10 * 10;
|
||||||
|
SET u3 = sign(10 * 10) * 10 * 20;
|
||||||
|
SET u4 = sign(-10 * 10) * -10 * 20;
|
||||||
|
|
||||||
|
SELECT u1, u2, u3, u4;
|
||||||
|
|
||||||
|
SET d1 = 1234;
|
||||||
|
SET d2 = 1234.12;
|
||||||
|
SET d3 = 1234.1234;
|
||||||
|
|
||||||
|
SELECT d1, d2, d3;
|
||||||
|
|
||||||
|
SET d1 = 12 * 100 + 34;
|
||||||
|
SET d2 = 12 * 100 + 34 + 0.12;
|
||||||
|
SET d3 = 12 * 100 + 34 + 0.1234;
|
||||||
|
|
||||||
|
SELECT d1, d2, d3;
|
||||||
|
END|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE FUNCTION sp_vars_check_ret1() RETURNS TINYINT
|
||||||
|
BEGIN
|
||||||
|
RETURN 1e200;
|
||||||
|
END|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE FUNCTION sp_vars_check_ret2() RETURNS TINYINT
|
||||||
|
BEGIN
|
||||||
|
RETURN 10 * 10 * 10;
|
||||||
|
END|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE FUNCTION sp_vars_check_ret3() RETURNS TINYINT
|
||||||
|
BEGIN
|
||||||
|
RETURN 'Hello, world';
|
||||||
|
END|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE FUNCTION sp_vars_check_ret4() RETURNS DECIMAL(64, 2)
|
||||||
|
BEGIN
|
||||||
|
RETURN 12 * 10 + 34 + 0.1234;
|
||||||
|
END|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
delimiter ;|
|
|
@ -2317,7 +2317,7 @@ CREATE TABLE t2(c2 char(2)) default charset = ujis;
|
||||||
INSERT INTO t1 VALUES(_ujis 0xA4A2);
|
INSERT INTO t1 VALUES(_ujis 0xA4A2);
|
||||||
CREATE PROCEDURE sp1()
|
CREATE PROCEDURE sp1()
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE a CHAR(1);
|
DECLARE a CHAR(2) CHARSET ujis;
|
||||||
DECLARE cur1 CURSOR FOR SELECT c1 FROM t1;
|
DECLARE cur1 CURSOR FOR SELECT c1 FROM t1;
|
||||||
OPEN cur1;
|
OPEN cur1;
|
||||||
FETCH cur1 INTO a;
|
FETCH cur1 INTO a;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
drop database if exists mysqltest1;
|
||||||
create schema foo;
|
create schema foo;
|
||||||
show create schema foo;
|
show create schema foo;
|
||||||
Database Create Database
|
Database Create Database
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
drop table if exists t1,t2;
|
drop table if exists t1,t2;
|
||||||
drop table if exists t1aa,t2aa;
|
drop table if exists t1aa,t2aa;
|
||||||
drop database if exists mysqltest;
|
drop database if exists mysqltest;
|
||||||
|
drop database if exists mysqltest1;
|
||||||
delete from mysql.user where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
delete from mysql.user where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
||||||
delete from mysql.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
delete from mysql.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
|
|
|
@ -10,5 +10,5 @@ user()
|
||||||
#
|
#
|
||||||
show processlist;
|
show processlist;
|
||||||
Id User Host db Command Time State Info
|
Id User Host db Command Time State Info
|
||||||
# root # test Sleep # NULL
|
<id> root <host> test <command> <time> <state> <info>
|
||||||
# root # test Query # NULL show processlist
|
<id> root <host> test <command> <time> <state> <info>
|
||||||
|
|
|
@ -25,6 +25,7 @@ count(*)
|
||||||
select count(*) from t2;
|
select count(*) from t2;
|
||||||
count(*)
|
count(*)
|
||||||
0
|
0
|
||||||
|
drop procedure if exists p1;
|
||||||
create procedure p1()
|
create procedure p1()
|
||||||
begin
|
begin
|
||||||
declare done integer default 0;
|
declare done integer default 0;
|
||||||
|
|
77
mysql-test/r/sp-destruct.result
Normal file
77
mysql-test/r/sp-destruct.result
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
use test;
|
||||||
|
drop procedure if exists bug14233;
|
||||||
|
drop function if exists bug14233;
|
||||||
|
drop table if exists t1;
|
||||||
|
drop view if exists v1;
|
||||||
|
create procedure bug14233()
|
||||||
|
set @x = 42;
|
||||||
|
create function bug14233_f() returns int
|
||||||
|
return 42;
|
||||||
|
create table t1 (id int);
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233();
|
||||||
|
alter table mysql.proc drop type;
|
||||||
|
call bug14233();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_f. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
flush table mysql.proc;
|
||||||
|
call bug14233();
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
flush table mysql.proc;
|
||||||
|
call bug14233();
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
flush table mysql.proc;
|
||||||
|
flush privileges;
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
insert into mysql.proc
|
||||||
|
(
|
||||||
|
db, name, type, specific_name, language, sql_data_access, is_deterministic,
|
||||||
|
security_type, param_list, returns, body, definer, created, modified,
|
||||||
|
sql_mode, comment
|
||||||
|
)
|
||||||
|
values
|
||||||
|
(
|
||||||
|
'test', 'bug14233_1', 'FUNCTION', 'bug14233_1', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'select count(*) from mysql.user',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_2', 'FUNCTION', 'bug14233_2', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'begin declare x int; select count(*) into x from mysql.user; end',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_3', 'PROCEDURE', 'bug14233_3', 'SQL', 'READS_SQL_DATA','NO',
|
||||||
|
'DEFINER', '', '',
|
||||||
|
'alksj wpsj sa ^#!@ ',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
);
|
||||||
|
select bug14233_1();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
create view v1 as select bug14233_1();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
select bug14233_2();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
create view v1 as select bug14233_2();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
call bug14233_3();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
drop trigger t1_ai;
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233_3();
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
drop trigger t1_ai;
|
||||||
|
drop table t1;
|
|
@ -1,3 +1,5 @@
|
||||||
|
drop procedure if exists p1|
|
||||||
|
drop procedure if exists p2|
|
||||||
create procedure p1()
|
create procedure p1()
|
||||||
begin
|
begin
|
||||||
prepare stmt from "select 1";
|
prepare stmt from "select 1";
|
||||||
|
|
|
@ -124,7 +124,7 @@ begin
|
||||||
declare x int;
|
declare x int;
|
||||||
set x = val+3;
|
set x = val+3;
|
||||||
end|
|
end|
|
||||||
ERROR 42000: No RETURN found in FUNCTION f
|
ERROR 42000: No RETURN found in FUNCTION test.f
|
||||||
create function f(val int) returns int
|
create function f(val int) returns int
|
||||||
begin
|
begin
|
||||||
declare x int;
|
declare x int;
|
||||||
|
@ -768,7 +768,7 @@ BEGIN
|
||||||
OPTIMIZE TABLE t1;
|
OPTIMIZE TABLE t1;
|
||||||
RETURN 1;
|
RETURN 1;
|
||||||
END|
|
END|
|
||||||
ERROR 0A000: OPTIMIZE TABLE is not allowed in stored procedures
|
ERROR 0A000: Not allowed to return a result set from a function
|
||||||
DROP FUNCTION IF EXISTS bug12995|
|
DROP FUNCTION IF EXISTS bug12995|
|
||||||
CREATE FUNCTION bug12995() RETURNS INT
|
CREATE FUNCTION bug12995() RETURNS INT
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -981,6 +981,8 @@ END |
|
||||||
drop table t1|
|
drop table t1|
|
||||||
drop function bug_13627_f|
|
drop function bug_13627_f|
|
||||||
drop function if exists bug12329;
|
drop function if exists bug12329;
|
||||||
|
Warnings:
|
||||||
|
Note 1305 FUNCTION bug12329 does not exist
|
||||||
create table t1 as select 1 a;
|
create table t1 as select 1 a;
|
||||||
create table t2 as select 1 a;
|
create table t2 as select 1 a;
|
||||||
create function bug12329() returns int return (select a from t1);
|
create function bug12329() returns int return (select a from t1);
|
||||||
|
@ -1055,3 +1057,34 @@ Db Name Type Definer Modified Created Security_type Comment
|
||||||
mysqltest2 p1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
|
mysqltest2 p1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
|
||||||
drop database mysqltest2;
|
drop database mysqltest2;
|
||||||
use test;
|
use test;
|
||||||
|
DROP FUNCTION IF EXISTS bug13012|
|
||||||
|
CREATE FUNCTION bug13012() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
RETURN 1;
|
||||||
|
END|
|
||||||
|
ERROR 0A000: Not allowed to return a result set from a function
|
||||||
|
CREATE FUNCTION bug13012() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
BACKUP TABLE t1 TO '/tmp';
|
||||||
|
RETURN 1;
|
||||||
|
END|
|
||||||
|
ERROR 0A000: Not allowed to return a result set from a function
|
||||||
|
CREATE FUNCTION bug13012() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
RESTORE TABLE t1 FROM '/tmp';
|
||||||
|
RETURN 1;
|
||||||
|
END|
|
||||||
|
ERROR 0A000: Not allowed to return a result set from a function
|
||||||
|
create table t1 (a int)|
|
||||||
|
CREATE PROCEDURE bug13012_1() REPAIR TABLE t1|
|
||||||
|
CREATE FUNCTION bug13012_2() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
CALL bug13012_1();
|
||||||
|
RETURN 1;
|
||||||
|
END|
|
||||||
|
SELECT bug13012_2()|
|
||||||
|
ERROR 0A000: Not allowed to return a result set from a function
|
||||||
|
drop table t1|
|
||||||
|
drop procedure bug13012_1|
|
||||||
|
drop function bug13012_2|
|
||||||
|
|
1077
mysql-test/r/sp-vars.result
Normal file
1077
mysql-test/r/sp-vars.result
Normal file
File diff suppressed because it is too large
Load diff
|
@ -248,13 +248,13 @@ return i+1|
|
||||||
call sub1("sub1a", (select 7))|
|
call sub1("sub1a", (select 7))|
|
||||||
call sub1("sub1b", (select max(i) from t2))|
|
call sub1("sub1b", (select max(i) from t2))|
|
||||||
call sub1("sub1c", (select i,d from t2 limit 1))|
|
call sub1("sub1c", (select i,d from t2 limit 1))|
|
||||||
|
ERROR 21000: Operand should contain 1 column(s)
|
||||||
call sub1("sub1d", (select 1 from (select 1) a))|
|
call sub1("sub1d", (select 1 from (select 1) a))|
|
||||||
call sub2("sub2")|
|
call sub2("sub2")|
|
||||||
select * from t1|
|
select * from t1|
|
||||||
id data
|
id data
|
||||||
sub1a 7
|
sub1a 7
|
||||||
sub1b 3
|
sub1b 3
|
||||||
sub1c 1
|
|
||||||
sub1d 1
|
sub1d 1
|
||||||
sub2 6
|
sub2 6
|
||||||
select sub3((select max(i) from t2))|
|
select sub3((select max(i) from t2))|
|
||||||
|
@ -2686,7 +2686,7 @@ call bug8937()|
|
||||||
s x y z
|
s x y z
|
||||||
16 3 1 6
|
16 3 1 6
|
||||||
a
|
a
|
||||||
3.2000
|
3.2
|
||||||
drop procedure bug8937|
|
drop procedure bug8937|
|
||||||
delete from t1|
|
delete from t1|
|
||||||
drop procedure if exists bug6900|
|
drop procedure if exists bug6900|
|
||||||
|
@ -2890,21 +2890,30 @@ create function bug9775(v1 char(1)) returns enum('a','b') return v1|
|
||||||
select bug9775('a'),bug9775('b'),bug9775('c')|
|
select bug9775('a'),bug9775('b'),bug9775('c')|
|
||||||
bug9775('a') bug9775('b') bug9775('c')
|
bug9775('a') bug9775('b') bug9775('c')
|
||||||
a b
|
a b
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'bug9775('c')' at row 1
|
||||||
drop function bug9775|
|
drop function bug9775|
|
||||||
create function bug9775(v1 int) returns enum('a','b') return v1|
|
create function bug9775(v1 int) returns enum('a','b') return v1|
|
||||||
select bug9775(1),bug9775(2),bug9775(3)|
|
select bug9775(1),bug9775(2),bug9775(3)|
|
||||||
bug9775(1) bug9775(2) bug9775(3)
|
bug9775(1) bug9775(2) bug9775(3)
|
||||||
a b
|
a b
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'bug9775(3)' at row 1
|
||||||
drop function bug9775|
|
drop function bug9775|
|
||||||
create function bug9775(v1 char(1)) returns set('a','b') return v1|
|
create function bug9775(v1 char(1)) returns set('a','b') return v1|
|
||||||
select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')|
|
select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')|
|
||||||
bug9775('a') bug9775('b') bug9775('a,b') bug9775('c')
|
bug9775('a') bug9775('b') bug9775('a,b') bug9775('c')
|
||||||
a b a,b
|
a b a
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'v1' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'bug9775('c')' at row 1
|
||||||
drop function bug9775|
|
drop function bug9775|
|
||||||
create function bug9775(v1 int) returns set('a','b') return v1|
|
create function bug9775(v1 int) returns set('a','b') return v1|
|
||||||
select bug9775(1),bug9775(2),bug9775(3),bug9775(4)|
|
select bug9775(1),bug9775(2),bug9775(3),bug9775(4)|
|
||||||
bug9775(1) bug9775(2) bug9775(3) bug9775(4)
|
bug9775(1) bug9775(2) bug9775(3) bug9775(4)
|
||||||
a b a,b
|
a b a,b
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'bug9775(4)' at row 1
|
||||||
drop function bug9775|
|
drop function bug9775|
|
||||||
drop function if exists bug8861|
|
drop function if exists bug8861|
|
||||||
create function bug8861(v1 int) returns year return v1|
|
create function bug8861(v1 int) returns year return v1|
|
||||||
|
@ -2927,12 +2936,10 @@ create procedure bug9004_2(x char(16))
|
||||||
call bug9004_1(x)|
|
call bug9004_1(x)|
|
||||||
call bug9004_1('12345678901234567')|
|
call bug9004_1('12345678901234567')|
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1265 Data truncated for column 'id' at row 1
|
Warning 1265 Data truncated for column 'x' at row 1
|
||||||
Warning 1265 Data truncated for column 'id' at row 2
|
|
||||||
call bug9004_2('12345678901234567890')|
|
call bug9004_2('12345678901234567890')|
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1265 Data truncated for column 'id' at row 1
|
Warning 1265 Data truncated for column 'x' at row 1
|
||||||
Warning 1265 Data truncated for column 'id' at row 2
|
|
||||||
delete from t1|
|
delete from t1|
|
||||||
drop procedure bug9004_1|
|
drop procedure bug9004_1|
|
||||||
drop procedure bug9004_2|
|
drop procedure bug9004_2|
|
||||||
|
@ -3527,14 +3534,15 @@ end|
|
||||||
call bug12589_1()|
|
call bug12589_1()|
|
||||||
Table Create Table
|
Table Create Table
|
||||||
tm1 CREATE TEMPORARY TABLE `tm1` (
|
tm1 CREATE TEMPORARY TABLE `tm1` (
|
||||||
`spv1` decimal(1,0) unsigned default NULL
|
`spv1` decimal(3,3) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect DECIMAL value: 'test'
|
Warning 1264 Out of range value for column 'spv1' at row 1
|
||||||
|
Warning 1366 Incorrect decimal value: 'test' for column 'spv1' at row 1
|
||||||
call bug12589_2()|
|
call bug12589_2()|
|
||||||
Table Create Table
|
Table Create Table
|
||||||
tm1 CREATE TEMPORARY TABLE `tm1` (
|
tm1 CREATE TEMPORARY TABLE `tm1` (
|
||||||
`spv1` decimal(6,3) unsigned default NULL
|
`spv1` decimal(6,3) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
call bug12589_3()|
|
call bug12589_3()|
|
||||||
Table Create Table
|
Table Create Table
|
||||||
|
@ -4016,34 +4024,37 @@ create procedure bug14643_1()
|
||||||
begin
|
begin
|
||||||
declare continue handler for sqlexception select 'boo' as 'Handler';
|
declare continue handler for sqlexception select 'boo' as 'Handler';
|
||||||
begin
|
begin
|
||||||
declare v int default x;
|
declare v int default undefined_var;
|
||||||
if v = 1 then
|
if v = 1 then
|
||||||
select 1;
|
select 1;
|
||||||
else
|
else
|
||||||
select 2;
|
select v, isnull(v);
|
||||||
end if;
|
end if;
|
||||||
end;
|
end;
|
||||||
end|
|
end|
|
||||||
create procedure bug14643_2()
|
create procedure bug14643_2()
|
||||||
begin
|
begin
|
||||||
declare continue handler for sqlexception select 'boo' as 'Handler';
|
declare continue handler for sqlexception select 'boo' as 'Handler';
|
||||||
case x
|
case undefined_var
|
||||||
when 1 then
|
when 1 then
|
||||||
select 1;
|
select 1;
|
||||||
else
|
else
|
||||||
select 2;
|
select 2;
|
||||||
end case;
|
end case;
|
||||||
|
select undefined_var;
|
||||||
end|
|
end|
|
||||||
call bug14643_1()|
|
call bug14643_1()|
|
||||||
Handler
|
Handler
|
||||||
boo
|
boo
|
||||||
2
|
v isnull(v)
|
||||||
2
|
NULL 1
|
||||||
call bug14643_2()|
|
call bug14643_2()|
|
||||||
Handler
|
Handler
|
||||||
boo
|
boo
|
||||||
2
|
2
|
||||||
2
|
2
|
||||||
|
Handler
|
||||||
|
boo
|
||||||
drop procedure bug14643_1|
|
drop procedure bug14643_1|
|
||||||
drop procedure bug14643_2|
|
drop procedure bug14643_2|
|
||||||
drop procedure if exists bug14304|
|
drop procedure if exists bug14304|
|
||||||
|
@ -4100,8 +4111,6 @@ x
|
||||||
4711
|
4711
|
||||||
drop procedure bug14376|
|
drop procedure bug14376|
|
||||||
drop procedure if exists p1|
|
drop procedure if exists p1|
|
||||||
Warnings:
|
|
||||||
Note 1305 PROCEDURE p1 does not exist
|
|
||||||
drop table if exists t1|
|
drop table if exists t1|
|
||||||
create table t1 (a varchar(255))|
|
create table t1 (a varchar(255))|
|
||||||
insert into t1 (a) values ("a - table column")|
|
insert into t1 (a) values ("a - table column")|
|
||||||
|
@ -4153,4 +4162,141 @@ A local variable in a nested compound statement takes precedence over table colu
|
||||||
a - local variable in a nested compound statement
|
a - local variable in a nested compound statement
|
||||||
A local variable in a nested compound statement takes precedence over table column in cursors
|
A local variable in a nested compound statement takes precedence over table column in cursors
|
||||||
a - local variable in a nested compound statement
|
a - local variable in a nested compound statement
|
||||||
|
drop procedure p1|
|
||||||
|
drop procedure if exists bug13012|
|
||||||
|
create procedure bug13012()
|
||||||
|
BEGIN
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
BACKUP TABLE t1 to '../tmp';
|
||||||
|
DROP TABLE t1;
|
||||||
|
RESTORE TABLE t1 FROM '../tmp';
|
||||||
|
END|
|
||||||
|
call bug13012()|
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 backup status OK
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 restore status OK
|
||||||
|
drop procedure bug13012|
|
||||||
|
create view v1 as select * from t1|
|
||||||
|
create procedure bug13012()
|
||||||
|
BEGIN
|
||||||
|
REPAIR TABLE t1,t2,t3,v1;
|
||||||
|
OPTIMIZE TABLE t1,t2,t3,v1;
|
||||||
|
ANALYZE TABLE t1,t2,t3,v1;
|
||||||
|
END|
|
||||||
|
call bug13012()|
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
test.t2 repair status OK
|
||||||
|
test.t3 repair error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 repair error 'test.v1' is not BASE TABLE
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status OK
|
||||||
|
test.t2 optimize status OK
|
||||||
|
test.t3 optimize error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 optimize error 'test.v1' is not BASE TABLE
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
test.t2 analyze status Table is already up to date
|
||||||
|
test.t3 analyze error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 analyze error 'test.v1' is not BASE TABLE
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
call bug13012()|
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
test.t2 repair status OK
|
||||||
|
test.t3 repair error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 repair error 'test.v1' is not BASE TABLE
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status OK
|
||||||
|
test.t2 optimize status OK
|
||||||
|
test.t3 optimize error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 optimize error 'test.v1' is not BASE TABLE
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
test.t2 analyze status Table is already up to date
|
||||||
|
test.t3 analyze error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 analyze error 'test.v1' is not BASE TABLE
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
call bug13012()|
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
test.t2 repair status OK
|
||||||
|
test.t3 repair error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 repair error 'test.v1' is not BASE TABLE
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status OK
|
||||||
|
test.t2 optimize status OK
|
||||||
|
test.t3 optimize error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 optimize error 'test.v1' is not BASE TABLE
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
test.t2 analyze status Table is already up to date
|
||||||
|
test.t3 analyze error Table 'test.t3' doesn't exist
|
||||||
|
test.v1 analyze error 'test.v1' is not BASE TABLE
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
|
drop procedure bug13012|
|
||||||
|
drop view v1;
|
||||||
|
select * from t1|
|
||||||
|
a
|
||||||
|
a - table column
|
||||||
|
drop schema if exists mysqltest1|
|
||||||
|
Warnings:
|
||||||
|
Note 1008 Can't drop database 'mysqltest1'; database doesn't exist
|
||||||
|
drop schema if exists mysqltest2|
|
||||||
|
Warnings:
|
||||||
|
Note 1008 Can't drop database 'mysqltest2'; database doesn't exist
|
||||||
|
drop schema if exists mysqltest3|
|
||||||
|
Warnings:
|
||||||
|
Note 1008 Can't drop database 'mysqltest3'; database doesn't exist
|
||||||
|
create schema mysqltest1|
|
||||||
|
create schema mysqltest2|
|
||||||
|
create schema mysqltest3|
|
||||||
|
use mysqltest3|
|
||||||
|
create procedure mysqltest1.p1 (out prequestid varchar(100))
|
||||||
|
begin
|
||||||
|
call mysqltest2.p2('call mysqltest3.p3(1, 2)');
|
||||||
|
end|
|
||||||
|
create procedure mysqltest2.p2(in psql text)
|
||||||
|
begin
|
||||||
|
declare lsql text;
|
||||||
|
set @lsql= psql;
|
||||||
|
prepare lstatement from @lsql;
|
||||||
|
execute lstatement;
|
||||||
|
deallocate prepare lstatement;
|
||||||
|
end|
|
||||||
|
create procedure mysqltest3.p3(in p1 int)
|
||||||
|
begin
|
||||||
|
select p1;
|
||||||
|
end|
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
|
||||||
|
drop schema if exists mysqltest1|
|
||||||
|
drop schema if exists mysqltest2|
|
||||||
|
drop schema if exists mysqltest3|
|
||||||
|
use test|
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using_big_test
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
0
|
|
||||||
CREATE TABLE t1 (id INTEGER);
|
CREATE TABLE t1 (id INTEGER);
|
||||||
CREATE TABLE t2 (id INTEGER);
|
CREATE TABLE t2 (id INTEGER);
|
||||||
INSERT INTO t1 (id) VALUES (1), (1), (1),(1);
|
INSERT INTO t1 (id) VALUES (1), (1), (1),(1);
|
||||||
|
@ -40,19 +39,19 @@ AVG(DISTINCT id)
|
||||||
512.5000
|
512.5000
|
||||||
SELECT SUM(DISTINCT id)/COUNT(DISTINCT id) FROM t1 GROUP BY id % 13;
|
SELECT SUM(DISTINCT id)/COUNT(DISTINCT id) FROM t1 GROUP BY id % 13;
|
||||||
SUM(DISTINCT id)/COUNT(DISTINCT id)
|
SUM(DISTINCT id)/COUNT(DISTINCT id)
|
||||||
513.50000
|
513.5000
|
||||||
508.00000
|
508.0000
|
||||||
509.00000
|
509.0000
|
||||||
510.00000
|
510.0000
|
||||||
511.00000
|
511.0000
|
||||||
512.00000
|
512.0000
|
||||||
513.00000
|
513.0000
|
||||||
514.00000
|
514.0000
|
||||||
515.00000
|
515.0000
|
||||||
516.00000
|
516.0000
|
||||||
517.00000
|
517.0000
|
||||||
511.50000
|
511.5000
|
||||||
512.50000
|
512.5000
|
||||||
INSERT INTO t1 SELECT id+1024 FROM t1;
|
INSERT INTO t1 SELECT id+1024 FROM t1;
|
||||||
INSERT INTO t1 SELECT id+2048 FROM t1;
|
INSERT INTO t1 SELECT id+2048 FROM t1;
|
||||||
INSERT INTO t1 SELECT id+4096 FROM t1;
|
INSERT INTO t1 SELECT id+4096 FROM t1;
|
||||||
|
|
|
@ -114,3 +114,26 @@ drop table t1;
|
||||||
select hex(cast(0x10 as binary(2)));
|
select hex(cast(0x10 as binary(2)));
|
||||||
hex(cast(0x10 as binary(2)))
|
hex(cast(0x10 as binary(2)))
|
||||||
1000
|
1000
|
||||||
|
create table t1 (b binary(2), vb varbinary(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, 0x412020);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'vb' at row 1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (c char(2), vc varchar(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, 0x412020);
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'vc' at row 1
|
||||||
|
drop table t1;
|
||||||
|
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
|
||||||
|
create table t1 (b binary(2), vb varbinary(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, NULL);
|
||||||
|
ERROR 22001: Data too long for column 'b' at row 1
|
||||||
|
insert into t1 values(NULL, 0x412020);
|
||||||
|
ERROR 22001: Data too long for column 'vb' at row 1
|
||||||
|
drop table t1;
|
||||||
|
set @@sql_mode= @old_sql_mode;
|
||||||
|
End of 5.0 tests
|
||||||
|
|
|
@ -1,11 +1,26 @@
|
||||||
drop procedure if exists sp1;
|
drop procedure if exists sp1;
|
||||||
create procedure sp1 () begin
|
CREATE PROCEDURE sp1()
|
||||||
declare v1, v2, v3, v4 decimal(16,12); declare v5 int;
|
BEGIN
|
||||||
set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = 0;
|
DECLARE v1, v2, v3, v4 DECIMAL(28,12);
|
||||||
while v5 < 100000 do
|
DECLARE v3_2, v4_2 DECIMAL(28, 12);
|
||||||
set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1;
|
DECLARE counter INT;
|
||||||
end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;//
|
SET v1 = 1;
|
||||||
|
SET v2 = 2;
|
||||||
|
SET v3 = 1000000000000;
|
||||||
|
SET v4 = 2000000000000;
|
||||||
|
SET counter = 0;
|
||||||
|
WHILE counter < 100000 DO
|
||||||
|
SET v1 = v1 + 0.000000000001;
|
||||||
|
SET v2 = v2 - 0.000000000001;
|
||||||
|
SET v3 = v3 + 1;
|
||||||
|
SET v4 = v4 - 1;
|
||||||
|
SET counter = counter + 1;
|
||||||
|
END WHILE;
|
||||||
|
SET v3_2 = v3 * 0.000000000001;
|
||||||
|
SET v4_2 = v4 * 0.000000000001;
|
||||||
|
SELECT v1, v2, v3, v3_2, v4, v4_2;
|
||||||
|
END//
|
||||||
call sp1()//
|
call sp1()//
|
||||||
v1 v2 v3 * 0.000000000001 v4 * 0.000000000001
|
v1 v2 v3 v3_2 v4 v4_2
|
||||||
1.000000100000 1.999999900000 1.000000100000 1.999999900000
|
1.000000100000 1.999999900000 1000000100000.000000000000 1.000000100000 1999999900000.000000000000 1.999999900000
|
||||||
drop procedure sp1;
|
drop procedure sp1;
|
||||||
|
|
|
@ -2383,20 +2383,25 @@ CREATE TABLE t1(id INT);
|
||||||
CREATE VIEW v1 AS SELECT id FROM t1;
|
CREATE VIEW v1 AS SELECT id FROM t1;
|
||||||
OPTIMIZE TABLE v1;
|
OPTIMIZE TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.v1 optimize note Unknown table 'test.v1'
|
test.v1 optimize error 'test.v1' is not BASE TABLE
|
||||||
|
Warnings:
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
ANALYZE TABLE v1;
|
ANALYZE TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.v1 analyze note Unknown table 'test.v1'
|
test.v1 analyze error 'test.v1' is not BASE TABLE
|
||||||
|
Warnings:
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
REPAIR TABLE v1;
|
REPAIR TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.v1 repair note Unknown table 'test.v1'
|
test.v1 repair error 'test.v1' is not BASE TABLE
|
||||||
|
Warnings:
|
||||||
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
OPTIMIZE TABLE v1;
|
OPTIMIZE TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.v1 optimize note Unknown table 'test.v1'
|
test.v1 optimize error 'test.v1' is not BASE TABLE
|
||||||
Warnings:
|
Warnings:
|
||||||
Error 1146 Table 'test.t1' doesn't exist
|
Error 1347 'test.v1' is not BASE TABLE
|
||||||
Error 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
create definer = current_user() sql security invoker view v1 as select 1;
|
create definer = current_user() sql security invoker view v1 as select 1;
|
||||||
show create view v1;
|
show create view v1;
|
||||||
|
|
|
@ -52,5 +52,6 @@ unlock tables;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
drop table t5;
|
drop table t5;
|
||||||
|
--system rm $MYSQL_TEST_DIR/var/tmp/t?.*
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
|
@ -1170,7 +1170,7 @@ INSERT INTO t1 VALUES(_ujis 0xA4A2);
|
||||||
DELIMITER |;
|
DELIMITER |;
|
||||||
CREATE PROCEDURE sp1()
|
CREATE PROCEDURE sp1()
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE a CHAR(1);
|
DECLARE a CHAR(2) CHARSET ujis;
|
||||||
DECLARE cur1 CURSOR FOR SELECT c1 FROM t1;
|
DECLARE cur1 CURSOR FOR SELECT c1 FROM t1;
|
||||||
OPEN cur1;
|
OPEN cur1;
|
||||||
FETCH cur1 INTO a;
|
FETCH cur1 INTO a;
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
#
|
#
|
||||||
# Just a couple of tests to make sure that schema works.
|
# Just a couple of tests to make sure that schema works.
|
||||||
#
|
#
|
||||||
|
# Drop mysqltest1 database, as it can left from the previous tests.
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop database if exists mysqltest1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
create schema foo;
|
create schema foo;
|
||||||
show create schema foo;
|
show create schema foo;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
drop table if exists t1,t2;
|
drop table if exists t1,t2;
|
||||||
drop table if exists t1aa,t2aa;
|
drop table if exists t1aa,t2aa;
|
||||||
drop database if exists mysqltest;
|
drop database if exists mysqltest;
|
||||||
|
drop database if exists mysqltest1;
|
||||||
|
|
||||||
delete from mysql.user where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
delete from mysql.user where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
||||||
delete from mysql.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
delete from mysql.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
||||||
|
|
|
@ -15,6 +15,6 @@ DROP USER mysqltest_1@'127.0.0.1/255.255.255.255';
|
||||||
connect (con1, 127.0.0.1, root, , test, $MASTER_MYPORT, );
|
connect (con1, 127.0.0.1, root, , test, $MASTER_MYPORT, );
|
||||||
--replace_column 1 #
|
--replace_column 1 #
|
||||||
select user();
|
select user();
|
||||||
--replace_column 1 # 6 # 3 #
|
--replace_column 1 <id> 3 <host> 5 <command> 6 <time> 7 <state> 8 <info>
|
||||||
show processlist;
|
show processlist;
|
||||||
connection default;
|
connection default;
|
||||||
|
|
|
@ -52,6 +52,9 @@ while ($1)
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
select count(*) from t1;
|
select count(*) from t1;
|
||||||
select count(*) from t2;
|
select count(*) from t2;
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists p1;
|
||||||
|
--enable_warnings
|
||||||
delimiter |;
|
delimiter |;
|
||||||
create procedure p1()
|
create procedure p1()
|
||||||
begin
|
begin
|
||||||
|
|
124
mysql-test/t/sp-destruct.test
Normal file
124
mysql-test/t/sp-destruct.test
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
#
|
||||||
|
# Destructive stored procedure tests
|
||||||
|
#
|
||||||
|
# We do horrible things to the mysql.proc table here, so any unexpected
|
||||||
|
# failures here might leave it in an undetermined state.
|
||||||
|
#
|
||||||
|
# In the case of trouble you might want to skip this.
|
||||||
|
#
|
||||||
|
|
||||||
|
# We're using --system things that probably doesn't work on Windows.
|
||||||
|
--source include/not_windows.inc
|
||||||
|
|
||||||
|
# Backup proc table
|
||||||
|
--system rm -rf var/master-data/mysql/backup
|
||||||
|
--system mkdir var/master-data/mysql/backup
|
||||||
|
--system cp var/master-data/mysql/proc.* var/master-data/mysql/backup/
|
||||||
|
|
||||||
|
use test;
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists bug14233;
|
||||||
|
drop function if exists bug14233;
|
||||||
|
drop table if exists t1;
|
||||||
|
drop view if exists v1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create procedure bug14233()
|
||||||
|
set @x = 42;
|
||||||
|
|
||||||
|
create function bug14233_f() returns int
|
||||||
|
return 42;
|
||||||
|
|
||||||
|
create table t1 (id int);
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233();
|
||||||
|
|
||||||
|
# Unsupported tampering with the mysql.proc definition
|
||||||
|
alter table mysql.proc drop type;
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
call bug14233();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
|
||||||
|
# Thrashing the .frm file
|
||||||
|
--system echo 'saljdlfa' > var/master-data/mysql/proc.frm
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
call bug14233();
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
|
||||||
|
# Drop the mysql.proc table
|
||||||
|
--system rm var/master-data/mysql/proc.*
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
call bug14233();
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
# Restore mysql.proc
|
||||||
|
--system mv var/master-data/mysql/backup/* var/master-data/mysql/
|
||||||
|
--system rmdir var/master-data/mysql/backup
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
flush privileges;
|
||||||
|
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
|
||||||
|
# Unsupported editing of mysql.proc, circumventing checks in "create ..."
|
||||||
|
insert into mysql.proc
|
||||||
|
(
|
||||||
|
db, name, type, specific_name, language, sql_data_access, is_deterministic,
|
||||||
|
security_type, param_list, returns, body, definer, created, modified,
|
||||||
|
sql_mode, comment
|
||||||
|
)
|
||||||
|
values
|
||||||
|
(
|
||||||
|
'test', 'bug14233_1', 'FUNCTION', 'bug14233_1', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'select count(*) from mysql.user',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_2', 'FUNCTION', 'bug14233_2', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'begin declare x int; select count(*) into x from mysql.user; end',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_3', 'PROCEDURE', 'bug14233_3', 'SQL', 'READS_SQL_DATA','NO',
|
||||||
|
'DEFINER', '', '',
|
||||||
|
'alksj wpsj sa ^#!@ ',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
);
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
select bug14233_1();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_1();
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
select bug14233_2();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_2();
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
call bug14233_3();
|
||||||
|
drop trigger t1_ai;
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233_3();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
# Clean-up
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
drop trigger t1_ai;
|
||||||
|
drop table t1;
|
|
@ -1,4 +1,10 @@
|
||||||
delimiter |;
|
delimiter |;
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists p1|
|
||||||
|
drop procedure if exists p2|
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Test Dynamic SQL in stored procedures. #############################
|
# Test Dynamic SQL in stored procedures. #############################
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
|
@ -1095,7 +1095,7 @@ delimiter |;
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP FUNCTION IF EXISTS bug12953|
|
DROP FUNCTION IF EXISTS bug12953|
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
--error ER_SP_BADSTATEMENT
|
--error ER_SP_NO_RETSET
|
||||||
CREATE FUNCTION bug12953() RETURNS INT
|
CREATE FUNCTION bug12953() RETURNS INT
|
||||||
BEGIN
|
BEGIN
|
||||||
OPTIMIZE TABLE t1;
|
OPTIMIZE TABLE t1;
|
||||||
|
@ -1410,7 +1410,6 @@ delimiter ;|
|
||||||
|
|
||||||
# BUG#12329: "Bogus error msg when executing PS with stored procedure after
|
# BUG#12329: "Bogus error msg when executing PS with stored procedure after
|
||||||
# SP was re-created". See also test for related bug#13399 in trigger.test
|
# SP was re-created". See also test for related bug#13399 in trigger.test
|
||||||
--disable_warnings
|
|
||||||
drop function if exists bug12329;
|
drop function if exists bug12329;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
create table t1 as select 1 a;
|
create table t1 as select 1 a;
|
||||||
|
@ -1518,6 +1517,44 @@ show procedure status;
|
||||||
drop database mysqltest2;
|
drop database mysqltest2;
|
||||||
use test;
|
use test;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#13012 "SP: REPAIR/BACKUP/RESTORE TABLE crashes the server"
|
||||||
|
#
|
||||||
|
delimiter |;
|
||||||
|
--disable_warnings
|
||||||
|
DROP FUNCTION IF EXISTS bug13012|
|
||||||
|
--enable_warnings
|
||||||
|
--error ER_SP_NO_RETSET
|
||||||
|
CREATE FUNCTION bug13012() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
RETURN 1;
|
||||||
|
END|
|
||||||
|
--error ER_SP_NO_RETSET
|
||||||
|
CREATE FUNCTION bug13012() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
BACKUP TABLE t1 TO '/tmp';
|
||||||
|
RETURN 1;
|
||||||
|
END|
|
||||||
|
--error ER_SP_NO_RETSET
|
||||||
|
CREATE FUNCTION bug13012() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
RESTORE TABLE t1 FROM '/tmp';
|
||||||
|
RETURN 1;
|
||||||
|
END|
|
||||||
|
create table t1 (a int)|
|
||||||
|
CREATE PROCEDURE bug13012_1() REPAIR TABLE t1|
|
||||||
|
CREATE FUNCTION bug13012_2() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
CALL bug13012_1();
|
||||||
|
RETURN 1;
|
||||||
|
END|
|
||||||
|
--error ER_SP_NO_RETSET
|
||||||
|
SELECT bug13012_2()|
|
||||||
|
drop table t1|
|
||||||
|
drop procedure bug13012_1|
|
||||||
|
drop function bug13012_2|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
#
|
#
|
||||||
|
|
1273
mysql-test/t/sp-vars.test
Normal file
1273
mysql-test/t/sp-vars.test
Normal file
File diff suppressed because it is too large
Load diff
|
@ -13,6 +13,8 @@
|
||||||
# Tests that require multiple connections, except security/privilege tests,
|
# Tests that require multiple connections, except security/privilege tests,
|
||||||
# go to sp-thread.
|
# go to sp-thread.
|
||||||
# Tests that uses 'goto' to into sp-goto.test (currently disabled)
|
# Tests that uses 'goto' to into sp-goto.test (currently disabled)
|
||||||
|
# Tests that destroys system tables (e.g. mysql.proc) for error testing
|
||||||
|
# go to sp-destruct.
|
||||||
|
|
||||||
use test;
|
use test;
|
||||||
|
|
||||||
|
@ -365,6 +367,7 @@ create function sub3(i int) returns int
|
||||||
|
|
||||||
call sub1("sub1a", (select 7))|
|
call sub1("sub1a", (select 7))|
|
||||||
call sub1("sub1b", (select max(i) from t2))|
|
call sub1("sub1b", (select max(i) from t2))|
|
||||||
|
--error ER_OPERAND_COLUMNS
|
||||||
call sub1("sub1c", (select i,d from t2 limit 1))|
|
call sub1("sub1c", (select i,d from t2 limit 1))|
|
||||||
call sub1("sub1d", (select 1 from (select 1) a))|
|
call sub1("sub1d", (select 1 from (select 1) a))|
|
||||||
call sub2("sub2")|
|
call sub2("sub2")|
|
||||||
|
@ -4795,12 +4798,12 @@ begin
|
||||||
declare continue handler for sqlexception select 'boo' as 'Handler';
|
declare continue handler for sqlexception select 'boo' as 'Handler';
|
||||||
|
|
||||||
begin
|
begin
|
||||||
declare v int default x;
|
declare v int default undefined_var;
|
||||||
|
|
||||||
if v = 1 then
|
if v = 1 then
|
||||||
select 1;
|
select 1;
|
||||||
else
|
else
|
||||||
select 2;
|
select v, isnull(v);
|
||||||
end if;
|
end if;
|
||||||
end;
|
end;
|
||||||
end|
|
end|
|
||||||
|
@ -4809,12 +4812,14 @@ create procedure bug14643_2()
|
||||||
begin
|
begin
|
||||||
declare continue handler for sqlexception select 'boo' as 'Handler';
|
declare continue handler for sqlexception select 'boo' as 'Handler';
|
||||||
|
|
||||||
case x
|
case undefined_var
|
||||||
when 1 then
|
when 1 then
|
||||||
select 1;
|
select 1;
|
||||||
else
|
else
|
||||||
select 2;
|
select 2;
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
|
select undefined_var;
|
||||||
end|
|
end|
|
||||||
|
|
||||||
call bug14643_1()|
|
call bug14643_1()|
|
||||||
|
@ -4908,8 +4913,10 @@ drop procedure bug14376|
|
||||||
# variable declarations. In MySQL 5.0 it's vice versa.
|
# variable declarations. In MySQL 5.0 it's vice versa.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
drop procedure if exists p1|
|
drop procedure if exists p1|
|
||||||
drop table if exists t1|
|
drop table if exists t1|
|
||||||
|
--enable_warnings
|
||||||
create table t1 (a varchar(255))|
|
create table t1 (a varchar(255))|
|
||||||
insert into t1 (a) values ("a - table column")|
|
insert into t1 (a) values ("a - table column")|
|
||||||
create procedure p1(a varchar(255))
|
create procedure p1(a varchar(255))
|
||||||
|
@ -4944,6 +4951,82 @@ begin
|
||||||
end;
|
end;
|
||||||
end|
|
end|
|
||||||
call p1("a - stored procedure parameter")|
|
call p1("a - stored procedure parameter")|
|
||||||
|
drop procedure p1|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#13012 "SP: REPAIR/BACKUP/RESTORE TABLE crashes the server"
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists bug13012|
|
||||||
|
--enable_warnings
|
||||||
|
create procedure bug13012()
|
||||||
|
BEGIN
|
||||||
|
REPAIR TABLE t1;
|
||||||
|
BACKUP TABLE t1 to '../tmp';
|
||||||
|
DROP TABLE t1;
|
||||||
|
RESTORE TABLE t1 FROM '../tmp';
|
||||||
|
END|
|
||||||
|
call bug13012()|
|
||||||
|
drop procedure bug13012|
|
||||||
|
create view v1 as select * from t1|
|
||||||
|
create procedure bug13012()
|
||||||
|
BEGIN
|
||||||
|
REPAIR TABLE t1,t2,t3,v1;
|
||||||
|
OPTIMIZE TABLE t1,t2,t3,v1;
|
||||||
|
ANALYZE TABLE t1,t2,t3,v1;
|
||||||
|
END|
|
||||||
|
call bug13012()|
|
||||||
|
call bug13012()|
|
||||||
|
call bug13012()|
|
||||||
|
drop procedure bug13012|
|
||||||
|
drop view v1;
|
||||||
|
select * from t1|
|
||||||
|
|
||||||
|
#
|
||||||
|
# A test case for Bug#15392 "Server crashes during prepared statement
|
||||||
|
# execute": make sure that stored procedure check for error conditions
|
||||||
|
# properly and do not continue execution if an error has been set.
|
||||||
|
#
|
||||||
|
# It's necessary to use several DBs because in the original code
|
||||||
|
# the successful return of mysql_change_db overrode the error from
|
||||||
|
# execution.
|
||||||
|
drop schema if exists mysqltest1|
|
||||||
|
drop schema if exists mysqltest2|
|
||||||
|
drop schema if exists mysqltest3|
|
||||||
|
create schema mysqltest1|
|
||||||
|
create schema mysqltest2|
|
||||||
|
create schema mysqltest3|
|
||||||
|
use mysqltest3|
|
||||||
|
|
||||||
|
create procedure mysqltest1.p1 (out prequestid varchar(100))
|
||||||
|
begin
|
||||||
|
call mysqltest2.p2('call mysqltest3.p3(1, 2)');
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure mysqltest2.p2(in psql text)
|
||||||
|
begin
|
||||||
|
declare lsql text;
|
||||||
|
set @lsql= psql;
|
||||||
|
prepare lstatement from @lsql;
|
||||||
|
execute lstatement;
|
||||||
|
deallocate prepare lstatement;
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure mysqltest3.p3(in p1 int)
|
||||||
|
begin
|
||||||
|
select p1;
|
||||||
|
end|
|
||||||
|
|
||||||
|
--error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
--error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
--error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
drop schema if exists mysqltest1|
|
||||||
|
drop schema if exists mysqltest2|
|
||||||
|
drop schema if exists mysqltest3|
|
||||||
|
use test|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
|
|
|
@ -68,3 +68,27 @@ drop table t1;
|
||||||
|
|
||||||
# check that cast appends trailing zeros
|
# check that cast appends trailing zeros
|
||||||
select hex(cast(0x10 as binary(2)));
|
select hex(cast(0x10 as binary(2)));
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #14299: BINARY space truncation should cause warning or error
|
||||||
|
#
|
||||||
|
create table t1 (b binary(2), vb varbinary(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, 0x412020);
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (c char(2), vc varchar(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, 0x412020);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
|
||||||
|
create table t1 (b binary(2), vb varbinary(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
--error ER_DATA_TOO_LONG
|
||||||
|
insert into t1 values(0x412020, NULL);
|
||||||
|
--error ER_DATA_TOO_LONG
|
||||||
|
insert into t1 values(NULL, 0x412020);
|
||||||
|
drop table t1;
|
||||||
|
set @@sql_mode= @old_sql_mode;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
||||||
|
|
|
@ -12,12 +12,31 @@ drop procedure if exists sp1;
|
||||||
|
|
||||||
delimiter //;
|
delimiter //;
|
||||||
#
|
#
|
||||||
create procedure sp1 () begin
|
CREATE PROCEDURE sp1()
|
||||||
declare v1, v2, v3, v4 decimal(16,12); declare v5 int;
|
BEGIN
|
||||||
set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = 0;
|
DECLARE v1, v2, v3, v4 DECIMAL(28,12);
|
||||||
while v5 < 100000 do
|
DECLARE v3_2, v4_2 DECIMAL(28, 12);
|
||||||
set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1;
|
DECLARE counter INT;
|
||||||
end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;//
|
|
||||||
|
SET v1 = 1;
|
||||||
|
SET v2 = 2;
|
||||||
|
SET v3 = 1000000000000;
|
||||||
|
SET v4 = 2000000000000;
|
||||||
|
SET counter = 0;
|
||||||
|
|
||||||
|
WHILE counter < 100000 DO
|
||||||
|
SET v1 = v1 + 0.000000000001;
|
||||||
|
SET v2 = v2 - 0.000000000001;
|
||||||
|
SET v3 = v3 + 1;
|
||||||
|
SET v4 = v4 - 1;
|
||||||
|
SET counter = counter + 1;
|
||||||
|
END WHILE;
|
||||||
|
|
||||||
|
SET v3_2 = v3 * 0.000000000001;
|
||||||
|
SET v4_2 = v4 * 0.000000000001;
|
||||||
|
|
||||||
|
SELECT v1, v2, v3, v3_2, v4, v4_2;
|
||||||
|
END//
|
||||||
#
|
#
|
||||||
call sp1()//
|
call sp1()//
|
||||||
#-- should return
|
#-- should return
|
||||||
|
|
402
sql/field.cc
402
sql/field.cc
|
@ -5859,44 +5859,52 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||||
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
||||||
uint copy_length;
|
uint copy_length;
|
||||||
|
|
||||||
/* See the comment for Field_long::store(long long) */
|
/* See the comment for Field_long::store(long long) */
|
||||||
DBUG_ASSERT(table->in_use == current_thd);
|
DBUG_ASSERT(table->in_use == current_thd);
|
||||||
|
|
||||||
/* Convert character set if necessary */
|
/* Convert character set if necessary */
|
||||||
if (String::needs_conversion(length, cs, field_charset, ¬_used))
|
if (String::needs_conversion(length, cs, field_charset, ¬_used))
|
||||||
{
|
{
|
||||||
uint conv_errors;
|
uint conv_errors;
|
||||||
tmpstr.copy(from, length, cs, field_charset, &conv_errors);
|
tmpstr.copy(from, length, cs, field_charset, &conv_errors);
|
||||||
from= tmpstr.ptr();
|
from= tmpstr.ptr();
|
||||||
length= tmpstr.length();
|
length= tmpstr.length();
|
||||||
if (conv_errors)
|
if (conv_errors)
|
||||||
error= 2;
|
error= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Make sure we don't break a multibyte sequence or copy malformed data. */
|
||||||
Make sure we don't break a multibyte sequence
|
|
||||||
as well as don't copy a malformed data.
|
|
||||||
*/
|
|
||||||
copy_length= field_charset->cset->well_formed_len(field_charset,
|
copy_length= field_charset->cset->well_formed_len(field_charset,
|
||||||
from,from+length,
|
from,from+length,
|
||||||
field_length/
|
field_length/
|
||||||
field_charset->mbmaxlen,
|
field_charset->mbmaxlen,
|
||||||
&well_formed_error);
|
&well_formed_error);
|
||||||
memcpy(ptr,from,copy_length);
|
memcpy(ptr,from,copy_length);
|
||||||
if (copy_length < field_length) // Append spaces if shorter
|
|
||||||
|
/* Append spaces if the string was shorter than the field. */
|
||||||
|
if (copy_length < field_length)
|
||||||
field_charset->cset->fill(field_charset,ptr+copy_length,
|
field_charset->cset->fill(field_charset,ptr+copy_length,
|
||||||
field_length-copy_length,
|
field_length-copy_length,
|
||||||
field_charset->pad_char);
|
field_charset->pad_char);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if we lost any important data (anything in a binary string,
|
||||||
|
or any non-space in others).
|
||||||
|
*/
|
||||||
if ((copy_length < length) && table->in_use->count_cuted_fields)
|
if ((copy_length < length) && table->in_use->count_cuted_fields)
|
||||||
{ // Check if we loosed some info
|
{
|
||||||
const char *end=from+length;
|
if (binary())
|
||||||
from+= copy_length;
|
|
||||||
from+= field_charset->cset->scan(field_charset, from, end,
|
|
||||||
MY_SEQ_SPACES);
|
|
||||||
if (from != end)
|
|
||||||
error= 2;
|
error= 2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *end=from+length;
|
||||||
|
from+= copy_length;
|
||||||
|
from+= field_charset->cset->scan(field_charset, from, end,
|
||||||
|
MY_SEQ_SPACES);
|
||||||
|
if (from != end)
|
||||||
|
error= 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
|
@ -6298,12 +6306,15 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||||
if ((copy_length < length) && table->in_use->count_cuted_fields &&
|
if ((copy_length < length) && table->in_use->count_cuted_fields &&
|
||||||
!error_code)
|
!error_code)
|
||||||
{
|
{
|
||||||
const char *end= from + length;
|
if (!binary())
|
||||||
from+= copy_length;
|
{
|
||||||
from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES);
|
const char *end= from + length;
|
||||||
/* If we lost only spaces then produce a NOTE, not a WARNING */
|
from+= copy_length;
|
||||||
if (from == end)
|
from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES);
|
||||||
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
|
/* If we lost only spaces then produce a NOTE, not a WARNING */
|
||||||
|
if (from == end)
|
||||||
|
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
|
||||||
|
}
|
||||||
error_code= WARN_DATA_TRUNCATED;
|
error_code= WARN_DATA_TRUNCATED;
|
||||||
}
|
}
|
||||||
if (error_code)
|
if (error_code)
|
||||||
|
@ -6794,6 +6805,7 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
||||||
{
|
{
|
||||||
flags|= BLOB_FLAG;
|
flags|= BLOB_FLAG;
|
||||||
share->blob_fields++;
|
share->blob_fields++;
|
||||||
|
/* TODO: why do not fill table->s->blob_field array here? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8358,6 +8370,350 @@ void create_field::init_for_tmp_table(enum_field_types sql_type_arg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize field definition for create
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
thd Thread handle
|
||||||
|
fld_name Field name
|
||||||
|
fld_type Field type
|
||||||
|
fld_length Field length
|
||||||
|
fld_decimals Decimal (if any)
|
||||||
|
fld_type_modifier Additional type information
|
||||||
|
fld_default_value Field default value (if any)
|
||||||
|
fld_on_update_value The value of ON UPDATE clause
|
||||||
|
fld_comment Field comment
|
||||||
|
fld_change Field change
|
||||||
|
fld_interval_list Interval list (if any)
|
||||||
|
fld_charset Field charset
|
||||||
|
fld_geom_type Field geometry type (if any)
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
FALSE on success
|
||||||
|
TRUE on error
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
||||||
|
char *fld_length, char *fld_decimals,
|
||||||
|
uint fld_type_modifier, Item *fld_default_value,
|
||||||
|
Item *fld_on_update_value, LEX_STRING *fld_comment,
|
||||||
|
char *fld_change, List<String> *fld_interval_list,
|
||||||
|
CHARSET_INFO *fld_charset, uint fld_geom_type)
|
||||||
|
{
|
||||||
|
uint sign_len, allowed_type_modifier= 0;
|
||||||
|
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
|
||||||
|
|
||||||
|
DBUG_ENTER("create_field::init()");
|
||||||
|
|
||||||
|
field= 0;
|
||||||
|
field_name= fld_name;
|
||||||
|
def= fld_default_value;
|
||||||
|
flags= fld_type_modifier;
|
||||||
|
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
|
||||||
|
Field::NEXT_NUMBER : Field::NONE);
|
||||||
|
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
|
||||||
|
if (decimals >= NOT_FIXED_DEC)
|
||||||
|
{
|
||||||
|
my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name,
|
||||||
|
NOT_FIXED_DEC-1);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql_type= fld_type;
|
||||||
|
length= 0;
|
||||||
|
change= fld_change;
|
||||||
|
interval= 0;
|
||||||
|
pack_length= key_length= 0;
|
||||||
|
charset= fld_charset;
|
||||||
|
geom_type= (Field::geometry_type) fld_geom_type;
|
||||||
|
interval_list.empty();
|
||||||
|
|
||||||
|
comment= *fld_comment;
|
||||||
|
/*
|
||||||
|
Set flag if this field doesn't have a default value
|
||||||
|
*/
|
||||||
|
if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) &&
|
||||||
|
(fld_type_modifier & NOT_NULL_FLAG) && fld_type != FIELD_TYPE_TIMESTAMP)
|
||||||
|
flags|= NO_DEFAULT_VALUE_FLAG;
|
||||||
|
|
||||||
|
if (fld_length && !(length= (uint) atoi(fld_length)))
|
||||||
|
fld_length= 0; /* purecov: inspected */
|
||||||
|
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
|
||||||
|
|
||||||
|
switch (fld_type) {
|
||||||
|
case FIELD_TYPE_TINY:
|
||||||
|
if (!fld_length)
|
||||||
|
length= MAX_TINYINT_WIDTH+sign_len;
|
||||||
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_SHORT:
|
||||||
|
if (!fld_length)
|
||||||
|
length= MAX_SMALLINT_WIDTH+sign_len;
|
||||||
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_INT24:
|
||||||
|
if (!fld_length)
|
||||||
|
length= MAX_MEDIUMINT_WIDTH+sign_len;
|
||||||
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_LONG:
|
||||||
|
if (!fld_length)
|
||||||
|
length= MAX_INT_WIDTH+sign_len;
|
||||||
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_LONGLONG:
|
||||||
|
if (!fld_length)
|
||||||
|
length= MAX_BIGINT_WIDTH;
|
||||||
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_NULL:
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_NEWDECIMAL:
|
||||||
|
if (!fld_length && !decimals)
|
||||||
|
length= 10;
|
||||||
|
if (length > DECIMAL_MAX_PRECISION)
|
||||||
|
{
|
||||||
|
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
|
||||||
|
DECIMAL_MAX_PRECISION);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
if (length < decimals)
|
||||||
|
{
|
||||||
|
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
length=
|
||||||
|
my_decimal_precision_to_length(length, decimals,
|
||||||
|
fld_type_modifier & UNSIGNED_FLAG);
|
||||||
|
pack_length=
|
||||||
|
my_decimal_get_binary_size(length, decimals);
|
||||||
|
break;
|
||||||
|
case MYSQL_TYPE_VARCHAR:
|
||||||
|
/*
|
||||||
|
Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
|
||||||
|
if they don't have a default value
|
||||||
|
*/
|
||||||
|
max_field_charlength= MAX_FIELD_VARCHARLENGTH;
|
||||||
|
break;
|
||||||
|
case MYSQL_TYPE_STRING:
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_BLOB:
|
||||||
|
case FIELD_TYPE_TINY_BLOB:
|
||||||
|
case FIELD_TYPE_LONG_BLOB:
|
||||||
|
case FIELD_TYPE_MEDIUM_BLOB:
|
||||||
|
case FIELD_TYPE_GEOMETRY:
|
||||||
|
if (fld_default_value)
|
||||||
|
{
|
||||||
|
/* Allow empty as default value. */
|
||||||
|
String str,*res;
|
||||||
|
res= fld_default_value->val_str(&str);
|
||||||
|
if (res->length())
|
||||||
|
{
|
||||||
|
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
|
||||||
|
fld_name); /* purecov: inspected */
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
def= 0;
|
||||||
|
}
|
||||||
|
flags|= BLOB_FLAG;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_YEAR:
|
||||||
|
if (!fld_length || length != 2)
|
||||||
|
length= 4; /* Default length */
|
||||||
|
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_FLOAT:
|
||||||
|
/* change FLOAT(precision) to FLOAT or DOUBLE */
|
||||||
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
|
if (fld_length && !fld_decimals)
|
||||||
|
{
|
||||||
|
uint tmp_length= length;
|
||||||
|
if (tmp_length > PRECISION_FOR_DOUBLE)
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
else if (tmp_length > PRECISION_FOR_FLOAT)
|
||||||
|
{
|
||||||
|
sql_type= FIELD_TYPE_DOUBLE;
|
||||||
|
length= DBL_DIG+7; /* -[digits].E+### */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
length= FLT_DIG+6; /* -[digits].E+## */
|
||||||
|
decimals= NOT_FIXED_DEC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!fld_length && !fld_decimals)
|
||||||
|
{
|
||||||
|
length= FLT_DIG+6;
|
||||||
|
decimals= NOT_FIXED_DEC;
|
||||||
|
}
|
||||||
|
if (length < decimals &&
|
||||||
|
decimals != NOT_FIXED_DEC)
|
||||||
|
{
|
||||||
|
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_DOUBLE:
|
||||||
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
|
if (!fld_length && !fld_decimals)
|
||||||
|
{
|
||||||
|
length= DBL_DIG+7;
|
||||||
|
decimals= NOT_FIXED_DEC;
|
||||||
|
}
|
||||||
|
if (length < decimals &&
|
||||||
|
decimals != NOT_FIXED_DEC)
|
||||||
|
{
|
||||||
|
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_TIMESTAMP:
|
||||||
|
if (!fld_length)
|
||||||
|
length= 14; /* Full date YYYYMMDDHHMMSS */
|
||||||
|
else if (length != 19)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We support only even TIMESTAMP lengths less or equal than 14
|
||||||
|
and 19 as length of 4.1 compatible representation.
|
||||||
|
*/
|
||||||
|
length= ((length+1)/2)*2; /* purecov: inspected */
|
||||||
|
length= min(length,14); /* purecov: inspected */
|
||||||
|
}
|
||||||
|
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
|
||||||
|
if (fld_default_value)
|
||||||
|
{
|
||||||
|
/* Grammar allows only NOW() value for ON UPDATE clause */
|
||||||
|
if (fld_default_value->type() == Item::FUNC_ITEM &&
|
||||||
|
((Item_func*)fld_default_value)->functype() == Item_func::NOW_FUNC)
|
||||||
|
{
|
||||||
|
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_DNUN_FIELD:
|
||||||
|
Field::TIMESTAMP_DN_FIELD);
|
||||||
|
/*
|
||||||
|
We don't need default value any longer moreover it is dangerous.
|
||||||
|
Everything handled by unireg_check further.
|
||||||
|
*/
|
||||||
|
def= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
|
||||||
|
Field::NONE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
|
||||||
|
or ON UPDATE values then for the sake of compatiblity we should treat
|
||||||
|
this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
|
||||||
|
have another TIMESTAMP column with auto-set option before this one)
|
||||||
|
or DEFAULT 0 (in other cases).
|
||||||
|
So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
|
||||||
|
replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
|
||||||
|
information about all TIMESTAMP fields in table will be availiable.
|
||||||
|
|
||||||
|
If we have TIMESTAMP NULL column without explicit DEFAULT value
|
||||||
|
we treat it as having DEFAULT NULL attribute.
|
||||||
|
*/
|
||||||
|
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD :
|
||||||
|
(flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
|
||||||
|
Field::NONE));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_DATE:
|
||||||
|
/* Old date type. */
|
||||||
|
if (protocol_version != PROTOCOL_VERSION-1)
|
||||||
|
sql_type= FIELD_TYPE_NEWDATE;
|
||||||
|
/* fall trough */
|
||||||
|
case FIELD_TYPE_NEWDATE:
|
||||||
|
length= 10;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_TIME:
|
||||||
|
length= 10;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_DATETIME:
|
||||||
|
length= 19;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_SET:
|
||||||
|
{
|
||||||
|
if (fld_interval_list->elements > sizeof(longlong)*8)
|
||||||
|
{
|
||||||
|
my_error(ER_TOO_BIG_SET, MYF(0), fld_name); /* purecov: inspected */
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
pack_length= get_set_pack_length(fld_interval_list->elements);
|
||||||
|
|
||||||
|
List_iterator<String> it(*fld_interval_list);
|
||||||
|
String *tmp;
|
||||||
|
while ((tmp= it++))
|
||||||
|
interval_list.push_back(tmp);
|
||||||
|
/*
|
||||||
|
Set fake length to 1 to pass the below conditions.
|
||||||
|
Real length will be set in mysql_prepare_table()
|
||||||
|
when we know the character set of the column
|
||||||
|
*/
|
||||||
|
length= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIELD_TYPE_ENUM:
|
||||||
|
{
|
||||||
|
/* Should be safe. */
|
||||||
|
pack_length= get_enum_pack_length(fld_interval_list->elements);
|
||||||
|
|
||||||
|
List_iterator<String> it(*fld_interval_list);
|
||||||
|
String *tmp;
|
||||||
|
while ((tmp= it++))
|
||||||
|
interval_list.push_back(tmp);
|
||||||
|
length= 1; /* See comment for FIELD_TYPE_SET above. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
|
DBUG_ASSERT(0); /* Impossible. */
|
||||||
|
break;
|
||||||
|
case MYSQL_TYPE_BIT:
|
||||||
|
{
|
||||||
|
if (!fld_length)
|
||||||
|
length= 1;
|
||||||
|
if (length > MAX_BIT_FIELD_LENGTH)
|
||||||
|
{
|
||||||
|
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name,
|
||||||
|
MAX_BIT_FIELD_LENGTH);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
pack_length= (length + 7) / 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIELD_TYPE_DECIMAL:
|
||||||
|
DBUG_ASSERT(0); /* Was obsolete */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flags & BLOB_FLAG) &&
|
||||||
|
((length > max_field_charlength && fld_type != FIELD_TYPE_SET &&
|
||||||
|
fld_type != FIELD_TYPE_ENUM &&
|
||||||
|
(fld_type != MYSQL_TYPE_VARCHAR || fld_default_value)) ||
|
||||||
|
(!length &&
|
||||||
|
fld_type != MYSQL_TYPE_STRING &&
|
||||||
|
fld_type != MYSQL_TYPE_VARCHAR && fld_type != FIELD_TYPE_GEOMETRY)))
|
||||||
|
{
|
||||||
|
my_error((fld_type == MYSQL_TYPE_VAR_STRING ||
|
||||||
|
fld_type == MYSQL_TYPE_VARCHAR ||
|
||||||
|
fld_type == MYSQL_TYPE_STRING) ? ER_TOO_BIG_FIELDLENGTH :
|
||||||
|
ER_TOO_BIG_DISPLAYWIDTH,
|
||||||
|
MYF(0),
|
||||||
|
fld_name, max_field_charlength); /* purecov: inspected */
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
fld_type_modifier&= AUTO_INCREMENT_FLAG;
|
||||||
|
if ((~allowed_type_modifier) & fld_type_modifier)
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(FALSE); /* success */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum_field_types get_blob_type_from_length(ulong length)
|
enum_field_types get_blob_type_from_length(ulong length)
|
||||||
{
|
{
|
||||||
enum_field_types type;
|
enum_field_types type;
|
||||||
|
|
18
sql/field.h
18
sql/field.h
|
@ -134,7 +134,19 @@ public:
|
||||||
null_bit == field->null_bit);
|
null_bit == field->null_bit);
|
||||||
}
|
}
|
||||||
virtual bool eq_def(Field *field);
|
virtual bool eq_def(Field *field);
|
||||||
|
|
||||||
|
/*
|
||||||
|
pack_length() returns size (in bytes) used to store field data in memory
|
||||||
|
(i.e. it returns the maximum size of the field in a row of the table,
|
||||||
|
which is located in RAM).
|
||||||
|
*/
|
||||||
virtual uint32 pack_length() const { return (uint32) field_length; }
|
virtual uint32 pack_length() const { return (uint32) field_length; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
pack_length_in_rec() returns size (in bytes) used to store field data on
|
||||||
|
storage (i.e. it returns the maximal size of the field in a row of the
|
||||||
|
table, which is located on disk).
|
||||||
|
*/
|
||||||
virtual uint32 pack_length_in_rec() const { return pack_length(); }
|
virtual uint32 pack_length_in_rec() const { return pack_length(); }
|
||||||
virtual uint32 sort_length() const { return pack_length(); }
|
virtual uint32 sort_length() const { return pack_length(); }
|
||||||
virtual void reset(void) { bzero(ptr,pack_length()); }
|
virtual void reset(void) { bzero(ptr,pack_length()); }
|
||||||
|
@ -1410,6 +1422,12 @@ public:
|
||||||
void init_for_tmp_table(enum_field_types sql_type_arg,
|
void init_for_tmp_table(enum_field_types sql_type_arg,
|
||||||
uint32 max_length, uint32 decimals,
|
uint32 max_length, uint32 decimals,
|
||||||
bool maybe_null, bool is_unsigned);
|
bool maybe_null, bool is_unsigned);
|
||||||
|
|
||||||
|
bool init(THD *thd, char *field_name, enum_field_types type, char *length,
|
||||||
|
char *decimals, uint type_modifier, Item *default_value,
|
||||||
|
Item *on_update_value, LEX_STRING *comment, char *change,
|
||||||
|
List<String> *interval_list, CHARSET_INFO *cs,
|
||||||
|
uint uint_geom_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -432,7 +432,7 @@ bool federated_db_init()
|
||||||
DBUG_ENTER("federated_db_init");
|
DBUG_ENTER("federated_db_init");
|
||||||
if (pthread_mutex_init(&federated_mutex, MY_MUTEX_INIT_FAST))
|
if (pthread_mutex_init(&federated_mutex, MY_MUTEX_INIT_FAST))
|
||||||
goto error;
|
goto error;
|
||||||
if (hash_init(&federated_open_tables, system_charset_info, 32, 0, 0,
|
if (!hash_init(&federated_open_tables, system_charset_info, 32, 0, 0,
|
||||||
(hash_get_key) federated_get_key, 0, 0))
|
(hash_get_key) federated_get_key, 0, 0))
|
||||||
{
|
{
|
||||||
federated_init= TRUE;
|
federated_init= TRUE;
|
||||||
|
@ -1343,7 +1343,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
|
||||||
query.append(FEDERATED_BTICK);
|
query.append(FEDERATED_BTICK);
|
||||||
query.append(FEDERATED_COMMA);
|
query.append(FEDERATED_COMMA);
|
||||||
}
|
}
|
||||||
query.length(query.length()- FEDERATED_COMMA_LEN);
|
query.length(query.length()- (FEDERATED_COMMA_LEN - 1));
|
||||||
query.append(FEDERATED_FROM);
|
query.append(FEDERATED_FROM);
|
||||||
query.append(FEDERATED_BTICK);
|
query.append(FEDERATED_BTICK);
|
||||||
|
|
||||||
|
|
199
sql/item.cc
199
sql/item.cc
|
@ -296,23 +296,6 @@ longlong Item::val_int_from_decimal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *Item::operator new(size_t size, Item *reuse, uint *rsize)
|
|
||||||
{
|
|
||||||
if (reuse && size <= reuse->rsize)
|
|
||||||
{
|
|
||||||
if (rsize)
|
|
||||||
(*rsize)= reuse->rsize;
|
|
||||||
reuse->cleanup();
|
|
||||||
delete reuse;
|
|
||||||
TRASH((void *)reuse, size);
|
|
||||||
return (void *)reuse;
|
|
||||||
}
|
|
||||||
if (rsize)
|
|
||||||
(*rsize)= (uint) size;
|
|
||||||
return (void *)sql_alloc((uint)size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Item::Item():
|
Item::Item():
|
||||||
rsize(0), name(0), orig_name(0), name_length(0), fixed(0),
|
rsize(0), name(0), orig_name(0), name_length(0), fixed(0),
|
||||||
is_autogenerated_name(TRUE),
|
is_autogenerated_name(TRUE),
|
||||||
|
@ -802,9 +785,41 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
Item_splocal methods
|
Item_sp_variable methods
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
double Item_splocal::val_real()
|
|
||||||
|
Item_sp_variable::Item_sp_variable(char *sp_var_name_str,
|
||||||
|
uint sp_var_name_length)
|
||||||
|
:m_thd(0)
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
, m_sp(0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
m_name.str= sp_var_name_str;
|
||||||
|
m_name.length= sp_var_name_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_sp_variable::fix_fields(THD *thd, Item **)
|
||||||
|
{
|
||||||
|
Item *it;
|
||||||
|
|
||||||
|
m_thd= thd; /* NOTE: this must be set before any this_xxx() */
|
||||||
|
it= this_item();
|
||||||
|
|
||||||
|
DBUG_ASSERT(it->fixed);
|
||||||
|
|
||||||
|
max_length= it->max_length;
|
||||||
|
decimals= it->decimals;
|
||||||
|
unsigned_flag= it->unsigned_flag;
|
||||||
|
fixed= 1;
|
||||||
|
collation.set(it->collation.collation, it->collation.derivation);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double Item_sp_variable::val_real()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed);
|
DBUG_ASSERT(fixed);
|
||||||
Item *it= this_item();
|
Item *it= this_item();
|
||||||
|
@ -814,7 +829,7 @@ double Item_splocal::val_real()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
longlong Item_splocal::val_int()
|
longlong Item_sp_variable::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed);
|
DBUG_ASSERT(fixed);
|
||||||
Item *it= this_item();
|
Item *it= this_item();
|
||||||
|
@ -824,13 +839,14 @@ longlong Item_splocal::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String *Item_splocal::val_str(String *sp)
|
String *Item_sp_variable::val_str(String *sp)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed);
|
DBUG_ASSERT(fixed);
|
||||||
Item *it= this_item();
|
Item *it= this_item();
|
||||||
String *res= it->val_str(sp);
|
String *res= it->val_str(sp);
|
||||||
|
|
||||||
null_value= it->null_value;
|
null_value= it->null_value;
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -854,11 +870,12 @@ String *Item_splocal::val_str(String *sp)
|
||||||
str_value.set(res->ptr(), res->length(), res->charset());
|
str_value.set(res->ptr(), res->length(), res->charset());
|
||||||
else
|
else
|
||||||
res->mark_as_const();
|
res->mark_as_const();
|
||||||
|
|
||||||
return &str_value;
|
return &str_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my_decimal *Item_splocal::val_decimal(my_decimal *decimal_value)
|
my_decimal *Item_sp_variable::val_decimal(my_decimal *decimal_value)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed);
|
DBUG_ASSERT(fixed);
|
||||||
Item *it= this_item();
|
Item *it= this_item();
|
||||||
|
@ -868,64 +885,53 @@ my_decimal *Item_splocal::val_decimal(my_decimal *decimal_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_splocal::is_null()
|
bool Item_sp_variable::is_null()
|
||||||
{
|
{
|
||||||
Item *it= this_item();
|
return this_item()->is_null();
|
||||||
return it->is_null();
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Item_splocal methods
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Item_splocal::Item_splocal(const LEX_STRING &sp_var_name,
|
||||||
|
uint sp_var_idx,
|
||||||
|
enum_field_types sp_var_type,
|
||||||
|
uint pos_in_q)
|
||||||
|
:Item_sp_variable(sp_var_name.str, sp_var_name.length),
|
||||||
|
m_var_idx(sp_var_idx), pos_in_query(pos_in_q)
|
||||||
|
{
|
||||||
|
maybe_null= TRUE;
|
||||||
|
|
||||||
|
m_type= sp_map_item_type(sp_var_type);
|
||||||
|
m_result_type= sp_map_result_type(sp_var_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item *
|
Item *
|
||||||
Item_splocal::this_item()
|
Item_splocal::this_item()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(owner == thd->spcont->owner);
|
DBUG_ASSERT(m_sp == m_thd->spcont->sp);
|
||||||
return thd->spcont->get_item(m_offset);
|
|
||||||
|
return m_thd->spcont->get_item(m_var_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Item *
|
||||||
|
Item_splocal::this_item() const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(m_sp == m_thd->spcont->sp);
|
||||||
|
|
||||||
|
return m_thd->spcont->get_item(m_var_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item **
|
Item **
|
||||||
Item_splocal::this_item_addr(THD *thd, Item **addr)
|
Item_splocal::this_item_addr(THD *thd, Item **)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(owner == thd->spcont->owner);
|
DBUG_ASSERT(m_sp == thd->spcont->sp);
|
||||||
return thd->spcont->get_item_addr(m_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
Item *
|
return thd->spcont->get_item_addr(m_var_idx);
|
||||||
Item_splocal::this_const_item() const
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(owner == thd->spcont->owner);
|
|
||||||
return thd->spcont->get_item(m_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
Item::Type
|
|
||||||
Item_splocal::type() const
|
|
||||||
{
|
|
||||||
if (thd && thd->spcont)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(owner == thd->spcont->owner);
|
|
||||||
return thd->spcont->get_item(m_offset)->type();
|
|
||||||
}
|
|
||||||
return NULL_ITEM; // Anything but SUBSELECT_ITEM
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Item_splocal::fix_fields(THD *thd_arg, Item **ref)
|
|
||||||
{
|
|
||||||
Item *it;
|
|
||||||
thd= thd_arg; // Must be set before this_item()
|
|
||||||
it= this_item();
|
|
||||||
DBUG_ASSERT(it->fixed);
|
|
||||||
max_length= it->max_length;
|
|
||||||
decimals= it->decimals;
|
|
||||||
unsigned_flag= it->unsigned_flag;
|
|
||||||
fixed= 1;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Item_splocal::cleanup()
|
|
||||||
{
|
|
||||||
fixed= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -934,7 +940,53 @@ void Item_splocal::print(String *str)
|
||||||
str->reserve(m_name.length+8);
|
str->reserve(m_name.length+8);
|
||||||
str->append(m_name.str, m_name.length);
|
str->append(m_name.str, m_name.length);
|
||||||
str->append('@');
|
str->append('@');
|
||||||
str->qs_append(m_offset);
|
str->qs_append(m_var_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Item_case_expr methods
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Item_case_expr::Item_case_expr(int case_expr_id)
|
||||||
|
:Item_sp_variable(STRING_WITH_LEN("case_expr")),
|
||||||
|
m_case_expr_id(case_expr_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *
|
||||||
|
Item_case_expr::this_item()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(m_sp == m_thd->spcont->sp);
|
||||||
|
|
||||||
|
return m_thd->spcont->get_case_expr(m_case_expr_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const Item *
|
||||||
|
Item_case_expr::this_item() const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(m_sp == m_thd->spcont->sp);
|
||||||
|
|
||||||
|
return m_thd->spcont->get_case_expr(m_case_expr_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item **
|
||||||
|
Item_case_expr::this_item_addr(THD *thd, Item **)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(m_sp == thd->spcont->sp);
|
||||||
|
|
||||||
|
return thd->spcont->get_case_expr_addr(m_case_expr_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_case_expr::print(String *str)
|
||||||
|
{
|
||||||
|
str->append(STRING_WITH_LEN("case_expr@"));
|
||||||
|
str->qs_append(m_case_expr_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1013,12 +1065,6 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_name_const::cleanup()
|
|
||||||
{
|
|
||||||
fixed= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Item_name_const::print(String *str)
|
void Item_name_const::print(String *str)
|
||||||
{
|
{
|
||||||
str->append(STRING_WITH_LEN("NAME_CONST("));
|
str->append(STRING_WITH_LEN("NAME_CONST("));
|
||||||
|
@ -3946,6 +3992,9 @@ int Item::save_in_field(Field *field, bool no_conversions)
|
||||||
str_value.set_quick(0, 0, cs);
|
str_value.set_quick(0, 0, cs);
|
||||||
return set_field_to_null_with_conversions(field, no_conversions);
|
return set_field_to_null_with_conversions(field, no_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOTE: If null_value == FALSE, "result" must be not NULL. */
|
||||||
|
|
||||||
field->set_notnull();
|
field->set_notnull();
|
||||||
error=field->store(result->ptr(),result->length(),cs);
|
error=field->store(result->ptr(),result->length(),cs);
|
||||||
str_value.set_quick(0, 0, cs);
|
str_value.set_quick(0, 0, cs);
|
||||||
|
@ -5207,7 +5256,7 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table)
|
||||||
set field_idx properly.
|
set field_idx properly.
|
||||||
*/
|
*/
|
||||||
(void)find_field_in_table(thd, table, field_name, (uint) strlen(field_name),
|
(void)find_field_in_table(thd, table, field_name, (uint) strlen(field_name),
|
||||||
0, 0, &field_idx, 0);
|
0, &field_idx);
|
||||||
thd->set_query_id= save_set_query_id;
|
thd->set_query_id= save_set_query_id;
|
||||||
triggers= table->triggers;
|
triggers= table->triggers;
|
||||||
}
|
}
|
||||||
|
|
291
sql/item.h
291
sql/item.h
|
@ -326,6 +326,48 @@ struct Name_resolution_context: Sql_alloc
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Store and restore the current state of a name resolution context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Name_resolution_context_state
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
TABLE_LIST *save_table_list;
|
||||||
|
TABLE_LIST *save_first_name_resolution_table;
|
||||||
|
TABLE_LIST *save_next_name_resolution_table;
|
||||||
|
bool save_resolve_in_select_list;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TABLE_LIST *save_next_local;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* Save the state of a name resolution context. */
|
||||||
|
void save_state(Name_resolution_context *context, TABLE_LIST *table_list)
|
||||||
|
{
|
||||||
|
save_table_list= context->table_list;
|
||||||
|
save_first_name_resolution_table= context->first_name_resolution_table;
|
||||||
|
save_next_name_resolution_table= (context->first_name_resolution_table) ?
|
||||||
|
context->first_name_resolution_table->
|
||||||
|
next_name_resolution_table :
|
||||||
|
NULL;
|
||||||
|
save_resolve_in_select_list= context->resolve_in_select_list;
|
||||||
|
save_next_local= table_list->next_local;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore a name resolution context from saved state. */
|
||||||
|
void restore_state(Name_resolution_context *context, TABLE_LIST *table_list)
|
||||||
|
{
|
||||||
|
table_list->next_local= save_next_local;
|
||||||
|
context->table_list= save_table_list;
|
||||||
|
context->first_name_resolution_table= save_first_name_resolution_table;
|
||||||
|
if (context->first_name_resolution_table)
|
||||||
|
context->first_name_resolution_table->
|
||||||
|
next_name_resolution_table= save_next_name_resolution_table;
|
||||||
|
context->resolve_in_select_list= save_resolve_in_select_list;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
typedef bool (Item::*Item_processor)(byte *arg);
|
typedef bool (Item::*Item_processor)(byte *arg);
|
||||||
|
@ -341,8 +383,6 @@ public:
|
||||||
{ return (void*) sql_alloc((uint) size); }
|
{ return (void*) sql_alloc((uint) size); }
|
||||||
static void *operator new(size_t size, MEM_ROOT *mem_root)
|
static void *operator new(size_t size, MEM_ROOT *mem_root)
|
||||||
{ return (void*) alloc_root(mem_root, (uint) size); }
|
{ return (void*) alloc_root(mem_root, (uint) size); }
|
||||||
/* Special for SP local variable assignment - reusing slots */
|
|
||||||
static void *operator new(size_t size, Item *reuse, uint *rsize);
|
|
||||||
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
|
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
|
||||||
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
|
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
|
||||||
|
|
||||||
|
@ -671,13 +711,13 @@ public:
|
||||||
current value and pointer to current Item otherwise.
|
current value and pointer to current Item otherwise.
|
||||||
*/
|
*/
|
||||||
virtual Item *this_item() { return this; }
|
virtual Item *this_item() { return this; }
|
||||||
|
virtual const Item *this_item() const { return this; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For SP local variable returns address of pointer to Item representing its
|
For SP local variable returns address of pointer to Item representing its
|
||||||
current value and pointer passed via parameter otherwise.
|
current value and pointer passed via parameter otherwise.
|
||||||
*/
|
*/
|
||||||
virtual Item **this_item_addr(THD *thd, Item **addr) { return addr; }
|
virtual Item **this_item_addr(THD *thd, Item **addr) { return addr; }
|
||||||
/* For SPs mostly. */
|
|
||||||
virtual Item *this_const_item() const { return const_cast<Item*>(this); }
|
|
||||||
|
|
||||||
// Row emulation
|
// Row emulation
|
||||||
virtual uint cols() { return 1; }
|
virtual uint cols() { return 1; }
|
||||||
|
@ -706,21 +746,32 @@ public:
|
||||||
|
|
||||||
class sp_head;
|
class sp_head;
|
||||||
|
|
||||||
/*
|
|
||||||
A reference to local SP variable (incl. reference to SP parameter), used in
|
|
||||||
runtime.
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
This item has a "value" item, defined as
|
|
||||||
this_item() = thd->spcont->get_item(m_offset)
|
|
||||||
and it delegates everything to that item (if !this_item() then this item
|
|
||||||
poses as Item_null) except for name, which is the name of SP local
|
|
||||||
variable.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Item_splocal : public Item
|
/*****************************************************************************
|
||||||
|
The class is a base class for representation of stored routine variables in
|
||||||
|
the Item-hierarchy. There are the following kinds of SP-vars:
|
||||||
|
- local variables (Item_splocal);
|
||||||
|
- CASE expression (Item_case_expr);
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Item_sp_variable :public Item
|
||||||
{
|
{
|
||||||
uint m_offset;
|
protected:
|
||||||
|
/*
|
||||||
|
THD, which is stored in fix_fields() and is used in this_item() to avoid
|
||||||
|
current_thd use.
|
||||||
|
*/
|
||||||
|
THD *m_thd;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LEX_STRING m_name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Buffer, pointing to the string value of the item. We need it to
|
||||||
|
protect internal buffer from changes. See comment to analogous
|
||||||
|
member in Item_param for more details.
|
||||||
|
*/
|
||||||
|
String str_value_ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
@ -728,11 +779,74 @@ public:
|
||||||
Routine to which this Item_splocal belongs. Used for checking if correct
|
Routine to which this Item_splocal belongs. Used for checking if correct
|
||||||
runtime context is used for variable handling.
|
runtime context is used for variable handling.
|
||||||
*/
|
*/
|
||||||
sp_head *owner;
|
sp_head *m_sp;
|
||||||
#endif
|
#endif
|
||||||
LEX_STRING m_name;
|
|
||||||
THD *thd;
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item_sp_variable(char *sp_var_name_str, uint sp_var_name_length);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool fix_fields(THD *thd, Item **);
|
||||||
|
|
||||||
|
double val_real();
|
||||||
|
longlong val_int();
|
||||||
|
String *val_str(String *sp);
|
||||||
|
my_decimal *val_decimal(my_decimal *decimal_value);
|
||||||
|
bool is_null();
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline void make_field(Send_field *field);
|
||||||
|
|
||||||
|
inline bool const_item() const;
|
||||||
|
|
||||||
|
inline int save_in_field(Field *field, bool no_conversions);
|
||||||
|
inline bool send(Protocol *protocol, String *str);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Item_sp_variable inline implementation.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline void Item_sp_variable::make_field(Send_field *field)
|
||||||
|
{
|
||||||
|
Item *it= this_item();
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
it->set_name(name, (uint) strlen(name), system_charset_info);
|
||||||
|
else
|
||||||
|
it->set_name(m_name.str, m_name.length, system_charset_info);
|
||||||
|
it->make_field(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Item_sp_variable::const_item() const
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int Item_sp_variable::save_in_field(Field *field, bool no_conversions)
|
||||||
|
{
|
||||||
|
return this_item()->save_in_field(field, no_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Item_sp_variable::send(Protocol *protocol, String *str)
|
||||||
|
{
|
||||||
|
return this_item()->send(protocol, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
A reference to local SP variable (incl. reference to SP parameter), used in
|
||||||
|
runtime.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Item_splocal :public Item_sp_variable
|
||||||
|
{
|
||||||
|
uint m_var_idx;
|
||||||
|
|
||||||
|
Type m_type;
|
||||||
|
Item_result m_result_type;
|
||||||
|
|
||||||
|
public:
|
||||||
/*
|
/*
|
||||||
Position of this reference to SP variable in the statement (the
|
Position of this reference to SP variable in the statement (the
|
||||||
statement itself is in sp_instr_stmt::m_query).
|
statement itself is in sp_instr_stmt::m_query).
|
||||||
|
@ -745,78 +859,94 @@ public:
|
||||||
*/
|
*/
|
||||||
uint pos_in_query;
|
uint pos_in_query;
|
||||||
|
|
||||||
Item_splocal(LEX_STRING name, uint offset, uint pos_in_q=0)
|
Item_splocal(const LEX_STRING &sp_var_name, uint sp_var_idx,
|
||||||
: m_offset(offset), m_name(name), thd(0), pos_in_query(pos_in_q)
|
enum_field_types sp_var_type, uint pos_in_q= 0);
|
||||||
{
|
|
||||||
maybe_null= TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For error printing */
|
|
||||||
inline LEX_STRING *my_name(LEX_STRING *get_name)
|
|
||||||
{
|
|
||||||
if (!get_name)
|
|
||||||
return &m_name;
|
|
||||||
(*get_name)= m_name;
|
|
||||||
return get_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_splocal() { return 1; } /* Needed for error checking */
|
bool is_splocal() { return 1; } /* Needed for error checking */
|
||||||
|
|
||||||
Item *this_item();
|
Item *this_item();
|
||||||
|
const Item *this_item() const;
|
||||||
Item **this_item_addr(THD *thd, Item **);
|
Item **this_item_addr(THD *thd, Item **);
|
||||||
Item *this_const_item() const;
|
|
||||||
|
|
||||||
bool fix_fields(THD *, Item **);
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
inline uint get_offset()
|
|
||||||
{
|
|
||||||
return m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Abstract methods inherited from Item. Just defer the call to
|
|
||||||
// the item in the frame
|
|
||||||
enum Type type() const;
|
|
||||||
|
|
||||||
double val_real();
|
|
||||||
longlong val_int();
|
|
||||||
String *val_str(String *sp);
|
|
||||||
my_decimal *val_decimal(my_decimal *);
|
|
||||||
bool is_null();
|
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
|
|
||||||
void make_field(Send_field *field)
|
public:
|
||||||
{
|
inline const LEX_STRING *my_name() const;
|
||||||
Item *it= this_item();
|
|
||||||
|
|
||||||
if (name)
|
inline uint get_var_idx() const;
|
||||||
it->set_name(name, (uint) strlen(name), system_charset_info);
|
|
||||||
else
|
|
||||||
it->set_name(m_name.str, m_name.length, system_charset_info);
|
|
||||||
it->make_field(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
Item_result result_type() const
|
inline enum Type type() const;
|
||||||
{
|
inline Item_result result_type() const;
|
||||||
return this_const_item()->result_type();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool const_item() const
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int save_in_field(Field *field, bool no_conversions)
|
|
||||||
{
|
|
||||||
return this_item()->save_in_field(field, no_conversions);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool send(Protocol *protocol, String *str)
|
|
||||||
{
|
|
||||||
return this_item()->send(protocol, str);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Item_splocal inline implementation.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline const LEX_STRING *Item_splocal::my_name() const
|
||||||
|
{
|
||||||
|
return &m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint Item_splocal::get_var_idx() const
|
||||||
|
{
|
||||||
|
return m_var_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline enum Item::Type Item_splocal::type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Item_result Item_splocal::result_type() const
|
||||||
|
{
|
||||||
|
return m_result_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
A reference to case expression in SP, used in runtime.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Item_case_expr :public Item_sp_variable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Item_case_expr(int case_expr_id);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item *this_item();
|
||||||
|
const Item *this_item() const;
|
||||||
|
Item **this_item_addr(THD *thd, Item **);
|
||||||
|
|
||||||
|
inline enum Type type() const;
|
||||||
|
inline Item_result result_type() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
NOTE: print() is intended to be used from views and for debug.
|
||||||
|
Item_case_expr can not occur in views, so here it is only for debug
|
||||||
|
purposes.
|
||||||
|
*/
|
||||||
|
void print(String *str);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_case_expr_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Item_case_expr inline implementation.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline enum Item::Type Item_case_expr::type() const
|
||||||
|
{
|
||||||
|
return this_item()->type();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Item_result Item_case_expr::result_type() const
|
||||||
|
{
|
||||||
|
return this_item()->result_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NAME_CONST(given_name, const_value).
|
NAME_CONST(given_name, const_value).
|
||||||
|
@ -843,7 +973,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fix_fields(THD *, Item **);
|
bool fix_fields(THD *, Item **);
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
enum Type type() const;
|
enum Type type() const;
|
||||||
double val_real();
|
double val_real();
|
||||||
|
|
|
@ -4720,7 +4720,7 @@ Item_func_sp::sp_result_field(void) const
|
||||||
dummy_table->s->table_name.str= empty_name;
|
dummy_table->s->table_name.str= empty_name;
|
||||||
dummy_table->s->db.str= empty_name;
|
dummy_table->s->db.str= empty_name;
|
||||||
}
|
}
|
||||||
field= m_sp->make_field(max_length, name, dummy_table);
|
field= m_sp->create_result_field(max_length, name, dummy_table);
|
||||||
DBUG_RETURN(field);
|
DBUG_RETURN(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4733,17 +4733,17 @@ Item_func_sp::sp_result_field(void) const
|
||||||
1 value = NULL or error
|
1 value = NULL or error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
bool
|
||||||
Item_func_sp::execute(Field **flp)
|
Item_func_sp::execute(Field **flp)
|
||||||
{
|
{
|
||||||
Item *it;
|
THD *thd= current_thd;
|
||||||
Field *f;
|
Field *f;
|
||||||
if (execute(&it))
|
|
||||||
{
|
/*
|
||||||
null_value= 1;
|
Get field in virtual tmp table to store result. Create the field if
|
||||||
context->process_error(current_thd);
|
invoked first time.
|
||||||
return 1;
|
*/
|
||||||
}
|
|
||||||
if (!(f= *flp))
|
if (!(f= *flp))
|
||||||
{
|
{
|
||||||
*flp= f= sp_result_field();
|
*flp= f= sp_result_field();
|
||||||
|
@ -4752,20 +4752,33 @@ Item_func_sp::execute(Field **flp)
|
||||||
f->null_ptr= (uchar *)&null_value;
|
f->null_ptr= (uchar *)&null_value;
|
||||||
f->null_bit= 1;
|
f->null_bit= 1;
|
||||||
}
|
}
|
||||||
it->save_in_field(f, 1);
|
|
||||||
return null_value= f->is_null();
|
/* Execute function and store the return value in the field. */
|
||||||
|
|
||||||
|
if (execute_impl(thd, f))
|
||||||
|
{
|
||||||
|
null_value= 1;
|
||||||
|
context->process_error(thd);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the field (the value) is not NULL. */
|
||||||
|
|
||||||
|
null_value= f->is_null();
|
||||||
|
|
||||||
|
return null_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
bool
|
||||||
Item_func_sp::execute(Item **itp)
|
Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_func_sp::execute");
|
bool err_status= TRUE;
|
||||||
THD *thd= current_thd;
|
|
||||||
int res= -1;
|
|
||||||
Sub_statement_state statement_state;
|
Sub_statement_state statement_state;
|
||||||
Security_context *save_security_ctx= thd->security_ctx, *save_ctx_func;
|
Security_context *save_security_ctx= thd->security_ctx, *save_ctx_func;
|
||||||
|
|
||||||
|
DBUG_ENTER("Item_func_sp::execute_impl");
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
if (context->security_ctx)
|
if (context->security_ctx)
|
||||||
{
|
{
|
||||||
|
@ -4782,7 +4795,7 @@ Item_func_sp::execute(Item **itp)
|
||||||
function call into binlog.
|
function call into binlog.
|
||||||
*/
|
*/
|
||||||
thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
|
thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
|
||||||
res= m_sp->execute_function(thd, args, arg_count, itp);
|
err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld);
|
||||||
thd->restore_sub_statement_state(&statement_state);
|
thd->restore_sub_statement_state(&statement_state);
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
@ -4792,7 +4805,7 @@ error:
|
||||||
#else
|
#else
|
||||||
error:
|
error:
|
||||||
#endif
|
#endif
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(err_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4888,7 +4901,7 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
|
||||||
DBUG_ENTER("Item_func_sp::tmp_table_field");
|
DBUG_ENTER("Item_func_sp::tmp_table_field");
|
||||||
|
|
||||||
if (m_sp)
|
if (m_sp)
|
||||||
res= m_sp->make_field(max_length, (const char *)name, t_arg);
|
res= m_sp->create_result_field(max_length, (const char*) name, t_arg);
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
res= Item_func::tmp_table_field(t_arg);
|
res= Item_func::tmp_table_field(t_arg);
|
||||||
|
|
|
@ -1374,8 +1374,8 @@ private:
|
||||||
Field *result_field;
|
Field *result_field;
|
||||||
char result_buf[64];
|
char result_buf[64];
|
||||||
|
|
||||||
int execute(Item **itp);
|
bool execute(Field **flp);
|
||||||
int execute(Field **flp);
|
bool execute_impl(THD *thd, Field *return_value_fld);
|
||||||
Field *sp_result_field(void) const;
|
Field *sp_result_field(void) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -686,6 +686,7 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list,
|
||||||
bool mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
|
bool mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
|
||||||
int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
|
int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
|
||||||
KEY_CACHE *dst_cache);
|
KEY_CACHE *dst_cache);
|
||||||
|
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list);
|
||||||
|
|
||||||
bool mysql_xa_recover(THD *thd);
|
bool mysql_xa_recover(THD *thd);
|
||||||
|
|
||||||
|
@ -820,18 +821,15 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
||||||
bool check_privileges, bool register_tree_change);
|
bool check_privileges, bool register_tree_change);
|
||||||
Field *
|
Field *
|
||||||
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||||
const char *name, const char *item_name,
|
const char *name, uint length,
|
||||||
const char *table_name, const char *db_name,
|
const char *item_name, const char *db_name,
|
||||||
uint length, Item **ref,
|
const char *table_name, Item **ref,
|
||||||
bool check_grants_table, bool check_grants_view,
|
bool check_privileges, bool allow_rowid,
|
||||||
bool allow_rowid,
|
|
||||||
uint *cached_field_index_ptr,
|
uint *cached_field_index_ptr,
|
||||||
bool register_tree_change, TABLE_LIST **actual_table);
|
bool register_tree_change, TABLE_LIST **actual_table);
|
||||||
Field *
|
Field *
|
||||||
find_field_in_table(THD *thd, TABLE *table, const char *name,
|
find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
||||||
uint length, bool check_grants, bool allow_rowid,
|
bool allow_rowid, uint *cached_field_index_ptr);
|
||||||
uint *cached_field_index_ptr,
|
|
||||||
Security_context *sctx);
|
|
||||||
Field *
|
Field *
|
||||||
find_field_in_table_sef(TABLE *table, const char *name);
|
find_field_in_table_sef(TABLE *table, const char *name);
|
||||||
|
|
||||||
|
@ -950,8 +948,9 @@ create_field * new_create_field(THD *thd, char *field_name, enum_field_types typ
|
||||||
uint uint_geom_type);
|
uint uint_geom_type);
|
||||||
void store_position_for_column(const char *name);
|
void store_position_for_column(const char *name);
|
||||||
bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
|
bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
|
||||||
Name_resolution_context *make_join_on_context(THD *thd, TABLE_LIST *left_op,
|
bool push_new_name_resolution_context(THD *thd,
|
||||||
TABLE_LIST *right_op);
|
TABLE_LIST *left_op,
|
||||||
|
TABLE_LIST *right_op);
|
||||||
void add_join_on(TABLE_LIST *b,Item *expr);
|
void add_join_on(TABLE_LIST *b,Item *expr);
|
||||||
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields);
|
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields);
|
||||||
bool add_proc_to_list(THD *thd, Item *item);
|
bool add_proc_to_list(THD *thd, Item *item);
|
||||||
|
@ -1140,8 +1139,8 @@ void unhex_type2(TYPELIB *lib);
|
||||||
uint check_word(TYPELIB *lib, const char *val, const char *end,
|
uint check_word(TYPELIB *lib, const char *val, const char *end,
|
||||||
const char **end_of_word);
|
const char **end_of_word);
|
||||||
|
|
||||||
bool is_keyword(const char *name, uint len);
|
|
||||||
|
|
||||||
|
bool is_keyword(const char *name, uint len);
|
||||||
|
|
||||||
#define MY_DB_OPT_FILE "db.opt"
|
#define MY_DB_OPT_FILE "db.opt"
|
||||||
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
|
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
|
||||||
|
|
|
@ -4697,12 +4697,12 @@ Disable with --skip-bdb (will save memory).",
|
||||||
{"bdb-lock-detect", OPT_BDB_LOCK,
|
{"bdb-lock-detect", OPT_BDB_LOCK,
|
||||||
"Berkeley lock detect (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec).",
|
"Berkeley lock detect (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec).",
|
||||||
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
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-log-direct", OPT_BDB_LOG_DIRECT,
|
{"bdb-log-direct", OPT_BDB_LOG_DIRECT,
|
||||||
"Turn off system buffering of BDB log files to avoid double caching.",
|
"Turn off system buffering of BDB log files to avoid double caching.",
|
||||||
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},
|
||||||
|
{"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,
|
{"bdb-no-recover", OPT_BDB_NO_RECOVER,
|
||||||
"Don't try to recover Berkeley DB tables on start.", 0, 0, 0, GET_NO_ARG,
|
"Don't try to recover Berkeley DB tables on start.", 0, 0, 0, GET_NO_ARG,
|
||||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
|
|
|
@ -791,9 +791,9 @@ struct show_var_st init_vars[]= {
|
||||||
{sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
|
{sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
|
||||||
SHOW_SYS},
|
SHOW_SYS},
|
||||||
{sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
|
{sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
|
||||||
{sys_myisam_use_mmap.name, (char*) &sys_myisam_use_mmap, SHOW_SYS},
|
|
||||||
|
|
||||||
{sys_myisam_stats_method.name, (char*) &sys_myisam_stats_method, SHOW_SYS},
|
{sys_myisam_stats_method.name, (char*) &sys_myisam_stats_method, SHOW_SYS},
|
||||||
|
{sys_myisam_use_mmap.name, (char*) &sys_myisam_use_mmap, SHOW_SYS},
|
||||||
|
|
||||||
#ifdef __NT__
|
#ifdef __NT__
|
||||||
{"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL},
|
{"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL},
|
||||||
|
@ -885,8 +885,8 @@ struct show_var_st init_vars[]= {
|
||||||
{"system_time_zone", system_time_zone, SHOW_CHAR},
|
{"system_time_zone", system_time_zone, SHOW_CHAR},
|
||||||
#endif
|
#endif
|
||||||
{"table_definition_cache", (char*) &table_def_size, SHOW_LONG},
|
{"table_definition_cache", (char*) &table_def_size, SHOW_LONG},
|
||||||
{"table_open_cache", (char*) &table_cache_size, SHOW_LONG},
|
|
||||||
{"table_lock_wait_timeout", (char*) &table_lock_wait_timeout, SHOW_LONG },
|
{"table_lock_wait_timeout", (char*) &table_lock_wait_timeout, SHOW_LONG },
|
||||||
|
{"table_open_cache", (char*) &table_cache_size, SHOW_LONG},
|
||||||
{sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
|
{sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
|
||||||
{sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
|
{sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
|
||||||
#ifdef HAVE_THR_SETCONCURRENCY
|
#ifdef HAVE_THR_SETCONCURRENCY
|
||||||
|
|
|
@ -4590,7 +4590,7 @@ ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 21000
|
||||||
nla "De gebruikte SELECT commando's hebben een verschillend aantal kolommen"
|
nla "De gebruikte SELECT commando's hebben een verschillend aantal kolommen"
|
||||||
eng "The used SELECT statements have a different number of columns"
|
eng "The used SELECT statements have a different number of columns"
|
||||||
est "Tulpade arv kasutatud SELECT lausetes ei kattu"
|
est "Tulpade arv kasutatud SELECT lausetes ei kattu"
|
||||||
ger "Die verwendeten SELECT-Befehle liefern eine unterschiedliche Anzahl von Feldern zurück"
|
ger "Die verwendeten SELECT-Befehle liefern unterschiedliche Anzahlen von Feldern zurück"
|
||||||
ita "La SELECT utilizzata ha un numero di colonne differente"
|
ita "La SELECT utilizzata ha un numero di colonne differente"
|
||||||
por "Os comandos SELECT usados têm diferente número de colunas"
|
por "Os comandos SELECT usados têm diferente número de colunas"
|
||||||
rus "éÓÐÏÌØÚÏ×ÁÎÎÙÅ ÏÐÅÒÁÔÏÒÙ ×ÙÂÏÒËÉ (SELECT) ÄÁÀÔ ÒÁÚÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ×"
|
rus "éÓÐÏÌØÚÏ×ÁÎÎÙÅ ÏÐÅÒÁÔÏÒÙ ×ÙÂÏÒËÉ (SELECT) ÄÁÀÔ ÒÁÚÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ×"
|
||||||
|
@ -5271,7 +5271,7 @@ ER_VIEW_SELECT_TMPTABLE
|
||||||
ukr "View SELECT ×ÉËÏÒÉÓÔÏ×Õ¤ ÔÉÍÞÁÓÏ×Õ ÔÁÂÌÉÃÀ '%-.64s'"
|
ukr "View SELECT ×ÉËÏÒÉÓÔÏ×Õ¤ ÔÉÍÞÁÓÏ×Õ ÔÁÂÌÉÃÀ '%-.64s'"
|
||||||
ER_VIEW_WRONG_LIST
|
ER_VIEW_WRONG_LIST
|
||||||
eng "View's SELECT and view's field list have different column counts"
|
eng "View's SELECT and view's field list have different column counts"
|
||||||
ger "SELECT- und Feldliste der Views haben eine unterschiedliche Anzahl von Spalten"
|
ger "SELECT- und Feldliste der Views haben unterschiedliche Anzahlen von Spalten"
|
||||||
rus "View SELECT É ÓÐÉÓÏË ÐÏÌÅÊ view ÉÍÅÀÔ ÒÁÚÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ×"
|
rus "View SELECT É ÓÐÉÓÏË ÐÏÌÅÊ view ÉÍÅÀÔ ÒÁÚÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ×"
|
||||||
ukr "View SELECT ¦ ÐÅÒÅÌ¦Ë ÓÔÏ×ÂÃ¦× view ÍÁÀÔØ Ò¦ÚÎÕ Ë¦ÌØ˦ÓÔØ ÓËÏ×Âæ×"
|
ukr "View SELECT ¦ ÐÅÒÅÌ¦Ë ÓÔÏ×ÂÃ¦× view ÍÁÀÔØ Ò¦ÚÎÕ Ë¦ÌØ˦ÓÔØ ÓËÏ×Âæ×"
|
||||||
ER_WARN_VIEW_MERGE
|
ER_WARN_VIEW_MERGE
|
||||||
|
@ -5482,7 +5482,7 @@ ER_CANT_CREATE_GEOMETRY_OBJECT 22003
|
||||||
ger "Kann kein Geometrieobjekt aus den Daten machen, die Sie dem GEOMETRY-Feld übergeben haben"
|
ger "Kann kein Geometrieobjekt aus den Daten machen, die Sie dem GEOMETRY-Feld übergeben haben"
|
||||||
ER_FAILED_ROUTINE_BREAK_BINLOG
|
ER_FAILED_ROUTINE_BREAK_BINLOG
|
||||||
eng "A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes"
|
eng "A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes"
|
||||||
ger "Eine Routine, die weder NO SQL noch READS SQL DATA in der Deklaration hat, schlug fehl und Binärlogging ist aktiv. Wenn Nicht-Transaktions-Tabellen atualisiert wurden, enthält das Binärlog ihre Änderungen nicht"
|
ger "Eine Routine, die weder NO SQL noch READS SQL DATA in der Deklaration hat, schlug fehl und Binärlogging ist aktiv. Wenn Nicht-Transaktions-Tabellen aktualisiert wurden, enthält das Binärlog ihre Änderungen nicht"
|
||||||
ER_BINLOG_UNSAFE_ROUTINE
|
ER_BINLOG_UNSAFE_ROUTINE
|
||||||
eng "This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)"
|
eng "This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)"
|
||||||
ger "Diese Routine hat weder DETERMINISTIC, NO SQL noch READS SQL DATA in der Deklaration und Binärlogging ist aktiv (*vielleicht* sollten Sie die weniger sichere Variable log_bin_trust_routine_creators verwenden)"
|
ger "Diese Routine hat weder DETERMINISTIC, NO SQL noch READS SQL DATA in der Deklaration und Binärlogging ist aktiv (*vielleicht* sollten Sie die weniger sichere Variable log_bin_trust_routine_creators verwenden)"
|
||||||
|
@ -5593,10 +5593,15 @@ ER_SP_BAD_VAR_SHADOW 42000
|
||||||
ger "Variable '%-.64s' muss mit `...` geschützt oder aber umbenannt werden"
|
ger "Variable '%-.64s' muss mit `...` geschützt oder aber umbenannt werden"
|
||||||
ER_TRG_NO_DEFINER
|
ER_TRG_NO_DEFINER
|
||||||
eng "No definer attribute for trigger '%-.64s'.'%-.64s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger."
|
eng "No definer attribute for trigger '%-.64s'.'%-.64s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger."
|
||||||
|
ger "Kein Definierer-Attribut für Trigger '%-.64s'.'%-.64s'. Der Trigger wird mit der Autorisierung des Aufrufers aktiviert, der möglicherweise keine zureichenden Berechtigungen hat. Bitte legen Sie den Trigger neu an."
|
||||||
ER_OLD_FILE_FORMAT
|
ER_OLD_FILE_FORMAT
|
||||||
eng "'%-.64s' has an old format, you should re-create the '%s' object(s)"
|
eng "'%-.64s' has an old format, you should re-create the '%s' object(s)"
|
||||||
|
ger "'%-.64s' hat altes Format, Sie sollten die '%s'-Objekt(e) neu erzeugen"
|
||||||
ER_SP_RECURSION_LIMIT
|
ER_SP_RECURSION_LIMIT
|
||||||
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.64s"
|
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.64s"
|
||||||
|
ger "Rekursionsgrenze %d (durch Variable max_sp_recursion_depth gegeben) wurde für Routine %.64s überschritten"
|
||||||
|
ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
eng "Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
|
||||||
ER_PARTITION_REQUIRES_VALUES_ERROR
|
ER_PARTITION_REQUIRES_VALUES_ERROR
|
||||||
eng "%s PARTITIONING requires definition of VALUES %s for each partition"
|
eng "%s PARTITIONING requires definition of VALUES %s for each partition"
|
||||||
swe "%s PARTITIONering kräver definition av VALUES %s för varje partition"
|
swe "%s PARTITIONering kräver definition av VALUES %s för varje partition"
|
||||||
|
|
107
sql/sp.cc
107
sql/sp.cc
|
@ -468,7 +468,7 @@ sp_returns_type(THD *thd, String &result, sp_head *sp)
|
||||||
bzero((char*) &share, sizeof(share));
|
bzero((char*) &share, sizeof(share));
|
||||||
table.in_use= thd;
|
table.in_use= thd;
|
||||||
table.s = &share;
|
table.s = &share;
|
||||||
field= sp->make_field(0, 0, &table);
|
field= sp->create_result_field(0, 0, &table);
|
||||||
field->sql_type(result);
|
field->sql_type(result);
|
||||||
delete field;
|
delete field;
|
||||||
}
|
}
|
||||||
|
@ -1447,21 +1447,23 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src)
|
||||||
first_no_prelock - If true, don't add tables or cache routines used by
|
first_no_prelock - If true, don't add tables or cache routines used by
|
||||||
the body of the first routine (i.e. *start)
|
the body of the first routine (i.e. *start)
|
||||||
will be executed in non-prelocked mode.
|
will be executed in non-prelocked mode.
|
||||||
|
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
|
||||||
NOTE
|
NOTE
|
||||||
If some function is missing this won't be reported here.
|
If some function is missing this won't be reported here.
|
||||||
Instead this fact will be discovered during query execution.
|
Instead this fact will be discovered during query execution.
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
TRUE - some tables were added
|
0 - success
|
||||||
FALSE - no tables were added.
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static int
|
||||||
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||||
Sroutine_hash_entry *start,
|
Sroutine_hash_entry *start,
|
||||||
bool first_no_prelock)
|
bool first_no_prelock, bool *tabs_changed)
|
||||||
{
|
{
|
||||||
bool result= FALSE;
|
int ret= 0;
|
||||||
|
bool tabschnd= 0; /* Set if tables changed */
|
||||||
bool first= TRUE;
|
bool first= TRUE;
|
||||||
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
|
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
|
||||||
|
|
||||||
|
@ -1482,12 +1484,50 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||||
name.m_name.str+= 1;
|
name.m_name.str+= 1;
|
||||||
name.m_name.length= name.m_qname.length - name.m_db.length - 1;
|
name.m_name.length= name.m_qname.length - name.m_db.length - 1;
|
||||||
|
|
||||||
if (db_find_routine(thd, type, &name, &sp) == SP_OK)
|
switch ((ret= db_find_routine(thd, type, &name, &sp)))
|
||||||
{
|
{
|
||||||
if (type == TYPE_ENUM_FUNCTION)
|
case SP_OK:
|
||||||
sp_cache_insert(&thd->sp_func_cache, sp);
|
{
|
||||||
else
|
if (type == TYPE_ENUM_FUNCTION)
|
||||||
sp_cache_insert(&thd->sp_proc_cache, sp);
|
sp_cache_insert(&thd->sp_func_cache, sp);
|
||||||
|
else
|
||||||
|
sp_cache_insert(&thd->sp_proc_cache, sp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SP_KEY_NOT_FOUND:
|
||||||
|
ret= SP_OK;
|
||||||
|
break;
|
||||||
|
case SP_OPEN_TABLE_FAILED:
|
||||||
|
/*
|
||||||
|
Force it to attempt opening it again on subsequent calls;
|
||||||
|
otherwise we will get one error message the first time, and
|
||||||
|
then ER_SP_PROC_TABLE_CORRUPT (below) on subsequent tries.
|
||||||
|
*/
|
||||||
|
mysql_proc_table_exists= 1;
|
||||||
|
/* Fall through */
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
Any error when loading an existing routine is either some problem
|
||||||
|
with the mysql.proc table, or a parse error because the contents
|
||||||
|
has been tampered with (in which case we clear that error).
|
||||||
|
*/
|
||||||
|
if (ret == SP_PARSE_ERROR)
|
||||||
|
thd->clear_error();
|
||||||
|
/*
|
||||||
|
If we cleared the parse error, or when db_find_routine() flagged
|
||||||
|
an error with it's return value without calling my_error(), we
|
||||||
|
set the generic "mysql.proc table corrupt" error here.
|
||||||
|
*/
|
||||||
|
if (!thd->net.report_error)
|
||||||
|
{
|
||||||
|
char n[NAME_LEN*2+2];
|
||||||
|
|
||||||
|
/* m_qname.str is not always \0 terminated */
|
||||||
|
memcpy(n, name.m_qname.str, name.m_qname.length);
|
||||||
|
n[name.m_qname.length]= '\0';
|
||||||
|
my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), n, ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sp)
|
if (sp)
|
||||||
|
@ -1495,12 +1535,15 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||||
if (!(first && first_no_prelock))
|
if (!(first && first_no_prelock))
|
||||||
{
|
{
|
||||||
sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines);
|
sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines);
|
||||||
result|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
|
tabschnd|=
|
||||||
|
sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
first= FALSE;
|
first= FALSE;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(result);
|
if (tabs_changed) /* it can be NULL */
|
||||||
|
*tabs_changed= tabschnd;
|
||||||
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1515,18 +1558,20 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||||
lex - LEX representing statement
|
lex - LEX representing statement
|
||||||
first_no_prelock - If true, don't add tables or cache routines used by
|
first_no_prelock - If true, don't add tables or cache routines used by
|
||||||
the body of the first routine (i.e. *start)
|
the body of the first routine (i.e. *start)
|
||||||
|
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
TRUE - some tables were added
|
0 - success
|
||||||
FALSE - no tables were added.
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
int
|
||||||
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
|
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock,
|
||||||
|
bool *tabs_changed)
|
||||||
{
|
{
|
||||||
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
(Sroutine_hash_entry *)lex->sroutines_list.first,
|
(Sroutine_hash_entry *)lex->sroutines_list.first,
|
||||||
first_no_prelock);
|
first_no_prelock, tabs_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1540,16 +1585,21 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
|
||||||
thd - thread context
|
thd - thread context
|
||||||
lex - LEX representing statement
|
lex - LEX representing statement
|
||||||
aux_lex - LEX representing view
|
aux_lex - LEX representing view
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 - success
|
||||||
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
int
|
||||||
sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
||||||
{
|
{
|
||||||
Sroutine_hash_entry **last_cached_routine_ptr=
|
Sroutine_hash_entry **last_cached_routine_ptr=
|
||||||
(Sroutine_hash_entry **)lex->sroutines_list.next;
|
(Sroutine_hash_entry **)lex->sroutines_list.next;
|
||||||
sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list);
|
sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list);
|
||||||
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
|
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
*last_cached_routine_ptr, FALSE);
|
*last_cached_routine_ptr, FALSE,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1563,12 +1613,18 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
||||||
thd - thread context
|
thd - thread context
|
||||||
lex - LEX respresenting statement
|
lex - LEX respresenting statement
|
||||||
triggers - triggers of the table
|
triggers - triggers of the table
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 - success
|
||||||
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
int
|
||||||
sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers)
|
Table_triggers_list *triggers)
|
||||||
{
|
{
|
||||||
|
int ret= 0;
|
||||||
|
|
||||||
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key))
|
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key))
|
||||||
{
|
{
|
||||||
Sroutine_hash_entry **last_cached_routine_ptr=
|
Sroutine_hash_entry **last_cached_routine_ptr=
|
||||||
|
@ -1586,10 +1642,11 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
|
ret= sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
*last_cached_routine_ptr,
|
*last_cached_routine_ptr,
|
||||||
FALSE);
|
FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
10
sql/sp.h
10
sql/sp.h
|
@ -84,11 +84,11 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
|
||||||
sp_name *rt, char rt_type);
|
sp_name *rt, char rt_type);
|
||||||
void sp_remove_not_own_routines(LEX *lex);
|
void sp_remove_not_own_routines(LEX *lex);
|
||||||
void sp_update_sp_used_routines(HASH *dst, HASH *src);
|
void sp_update_sp_used_routines(HASH *dst, HASH *src);
|
||||||
bool sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
|
||||||
bool first_no_prelock);
|
bool first_no_prelock, bool *tabs_changed);
|
||||||
void sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
|
||||||
LEX *aux_lex);
|
LEX *aux_lex);
|
||||||
void sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers);
|
Table_triggers_list *triggers);
|
||||||
|
|
||||||
extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
|
extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
|
||||||
|
|
973
sql/sp_head.cc
973
sql/sp_head.cc
File diff suppressed because it is too large
Load diff
|
@ -33,6 +33,9 @@
|
||||||
Item_result
|
Item_result
|
||||||
sp_map_result_type(enum enum_field_types type);
|
sp_map_result_type(enum enum_field_types type);
|
||||||
|
|
||||||
|
Item::Type
|
||||||
|
sp_map_item_type(enum enum_field_types type);
|
||||||
|
|
||||||
uint
|
uint
|
||||||
sp_get_flags_for_command(LEX *lex);
|
sp_get_flags_for_command(LEX *lex);
|
||||||
|
|
||||||
|
@ -123,12 +126,9 @@ public:
|
||||||
/* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
|
/* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
|
||||||
int m_type;
|
int m_type;
|
||||||
uint m_flags; // Boolean attributes of a stored routine
|
uint m_flags; // Boolean attributes of a stored routine
|
||||||
enum enum_field_types m_returns; // For FUNCTIONs only
|
|
||||||
Field::geometry_type m_geom_returns;
|
create_field m_return_field_def; /* This is used for FUNCTIONs only. */
|
||||||
CHARSET_INFO *m_returns_cs; // For FUNCTIONs only
|
|
||||||
TYPELIB *m_returns_typelib; // For FUNCTIONs only
|
|
||||||
uint m_returns_len; // For FUNCTIONs only
|
|
||||||
uint m_returns_pack; // For FUNCTIONs only
|
|
||||||
const uchar *m_tmp_query; // Temporary pointer to sub query string
|
const uchar *m_tmp_query; // Temporary pointer to sub query string
|
||||||
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
|
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
|
||||||
st_sp_chistics *m_chistics;
|
st_sp_chistics *m_chistics;
|
||||||
|
@ -202,9 +202,6 @@ public:
|
||||||
void
|
void
|
||||||
init_strings(THD *thd, LEX *lex, sp_name *name);
|
init_strings(THD *thd, LEX *lex, sp_name *name);
|
||||||
|
|
||||||
TYPELIB *
|
|
||||||
create_typelib(List<String> *src);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
create(THD *thd);
|
create(THD *thd);
|
||||||
|
|
||||||
|
@ -214,10 +211,10 @@ public:
|
||||||
void
|
void
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
int
|
bool
|
||||||
execute_function(THD *thd, Item **args, uint argcount, Item **resp);
|
execute_function(THD *thd, Item **args, uint argcount, Field *return_fld);
|
||||||
|
|
||||||
int
|
bool
|
||||||
execute_procedure(THD *thd, List<Item> *args);
|
execute_procedure(THD *thd, List<Item> *args);
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -278,7 +275,12 @@ public:
|
||||||
|
|
||||||
char *create_string(THD *thd, ulong *lenp);
|
char *create_string(THD *thd, ulong *lenp);
|
||||||
|
|
||||||
Field *make_field(uint max_length, const char *name, TABLE *dummy);
|
Field *create_result_field(uint field_max_length, const char *field_name,
|
||||||
|
TABLE *table);
|
||||||
|
|
||||||
|
bool fill_field_definition(THD *thd, LEX *lex,
|
||||||
|
enum enum_field_types field_type,
|
||||||
|
create_field *field_def);
|
||||||
|
|
||||||
void set_info(longlong created, longlong modified,
|
void set_info(longlong created, longlong modified,
|
||||||
st_sp_chistics *chistics, ulong sql_mode);
|
st_sp_chistics *chistics, ulong sql_mode);
|
||||||
|
@ -363,7 +365,7 @@ private:
|
||||||
*/
|
*/
|
||||||
HASH m_sptabs;
|
HASH m_sptabs;
|
||||||
|
|
||||||
int
|
bool
|
||||||
execute(THD *thd);
|
execute(THD *thd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1074,6 +1076,31 @@ private:
|
||||||
}; // class sp_instr_error : public sp_instr
|
}; // class sp_instr_error : public sp_instr
|
||||||
|
|
||||||
|
|
||||||
|
class sp_instr_set_case_expr :public sp_instr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
sp_instr_set_case_expr(uint ip, sp_pcontext *ctx, uint case_expr_id,
|
||||||
|
Item *case_expr, LEX *lex)
|
||||||
|
:sp_instr(ip, ctx), m_case_expr_id(case_expr_id), m_case_expr(case_expr),
|
||||||
|
m_lex_keeper(lex, TRUE)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual int execute(THD *thd, uint *nextp);
|
||||||
|
|
||||||
|
virtual int exec_core(THD *thd, uint *nextp);
|
||||||
|
|
||||||
|
virtual void print(String *str);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint m_case_expr_id;
|
||||||
|
Item *m_case_expr;
|
||||||
|
sp_lex_keeper m_lex_keeper;
|
||||||
|
|
||||||
|
}; // class sp_instr_set_case_expr : public sp_instr
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
bool
|
bool
|
||||||
sp_change_security_context(THD *thd, sp_head *sp,
|
sp_change_security_context(THD *thd, sp_head *sp,
|
||||||
|
@ -1086,8 +1113,10 @@ TABLE_LIST *
|
||||||
sp_add_to_query_tables(THD *thd, LEX *lex,
|
sp_add_to_query_tables(THD *thd, LEX *lex,
|
||||||
const char *db, const char *name,
|
const char *db, const char *name,
|
||||||
thr_lock_type locktype);
|
thr_lock_type locktype);
|
||||||
|
Item *
|
||||||
|
sp_prepare_func_item(THD* thd, Item **it_addr);
|
||||||
|
|
||||||
Item *sp_eval_func_item(THD *thd, Item **it, enum_field_types type,
|
bool
|
||||||
Item *reuse, bool use_callers_arena);
|
sp_eval_expr(THD *thd, Field *result_field, Item *expr_item);
|
||||||
|
|
||||||
#endif /* _SP_HEAD_H_ */
|
#endif /* _SP_HEAD_H_ */
|
||||||
|
|
|
@ -51,21 +51,26 @@ sp_cond_check(LEX_STRING *sqlstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
sp_pcontext::sp_pcontext(sp_pcontext *prev)
|
sp_pcontext::sp_pcontext(sp_pcontext *prev)
|
||||||
: Sql_alloc(), m_psubsize(0), m_csubsize(0), m_hsubsize(0),
|
:Sql_alloc(), m_total_pvars(0), m_csubsize(0), m_hsubsize(0),
|
||||||
m_handlers(0), m_parent(prev), m_pboundary(0)
|
m_handlers(0), m_parent(prev), m_pboundary(0)
|
||||||
{
|
{
|
||||||
VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8));
|
VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8));
|
||||||
|
VOID(my_init_dynamic_array(&m_case_expr_id_lst, sizeof(int), 16, 8));
|
||||||
VOID(my_init_dynamic_array(&m_cond, sizeof(sp_cond_type_t *), 16, 8));
|
VOID(my_init_dynamic_array(&m_cond, sizeof(sp_cond_type_t *), 16, 8));
|
||||||
VOID(my_init_dynamic_array(&m_cursor, sizeof(LEX_STRING), 16, 8));
|
VOID(my_init_dynamic_array(&m_cursor, sizeof(LEX_STRING), 16, 8));
|
||||||
VOID(my_init_dynamic_array(&m_handler, sizeof(sp_cond_type_t *), 16, 8));
|
VOID(my_init_dynamic_array(&m_handler, sizeof(sp_cond_type_t *), 16, 8));
|
||||||
m_label.empty();
|
m_label.empty();
|
||||||
m_children.empty();
|
m_children.empty();
|
||||||
if (!prev)
|
if (!prev)
|
||||||
|
{
|
||||||
m_poffset= m_coffset= 0;
|
m_poffset= m_coffset= 0;
|
||||||
|
m_num_case_exprs= 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_poffset= prev->current_pvars();
|
m_poffset= prev->m_poffset + prev->m_total_pvars;
|
||||||
m_coffset= prev->current_cursors();
|
m_coffset= prev->current_cursors();
|
||||||
|
m_num_case_exprs= prev->get_num_case_exprs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +86,7 @@ sp_pcontext::destroy()
|
||||||
m_children.empty();
|
m_children.empty();
|
||||||
m_label.empty();
|
m_label.empty();
|
||||||
delete_dynamic(&m_pvar);
|
delete_dynamic(&m_pvar);
|
||||||
|
delete_dynamic(&m_case_expr_id_lst);
|
||||||
delete_dynamic(&m_cond);
|
delete_dynamic(&m_cond);
|
||||||
delete_dynamic(&m_cursor);
|
delete_dynamic(&m_cursor);
|
||||||
delete_dynamic(&m_handler);
|
delete_dynamic(&m_handler);
|
||||||
|
@ -99,16 +105,19 @@ sp_pcontext::push_context()
|
||||||
sp_pcontext *
|
sp_pcontext *
|
||||||
sp_pcontext::pop_context()
|
sp_pcontext::pop_context()
|
||||||
{
|
{
|
||||||
uint submax= max_pvars();
|
m_parent->m_total_pvars= m_parent->m_total_pvars + m_total_pvars;
|
||||||
|
|
||||||
if (submax > m_parent->m_psubsize)
|
uint submax= max_handlers();
|
||||||
m_parent->m_psubsize= submax;
|
|
||||||
submax= max_handlers();
|
|
||||||
if (submax > m_parent->m_hsubsize)
|
if (submax > m_parent->m_hsubsize)
|
||||||
m_parent->m_hsubsize= submax;
|
m_parent->m_hsubsize= submax;
|
||||||
|
|
||||||
submax= max_cursors();
|
submax= max_cursors();
|
||||||
if (submax > m_parent->m_csubsize)
|
if (submax > m_parent->m_csubsize)
|
||||||
m_parent->m_csubsize= submax;
|
m_parent->m_csubsize= submax;
|
||||||
|
|
||||||
|
if (m_num_case_exprs > m_parent->m_num_case_exprs)
|
||||||
|
m_parent->m_num_case_exprs= m_num_case_exprs;
|
||||||
|
|
||||||
return m_parent;
|
return m_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,26 +200,29 @@ sp_pcontext::find_pvar(uint offset)
|
||||||
return NULL; // index out of bounds
|
return NULL; // index out of bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
sp_pvar_t *
|
||||||
sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
|
sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
|
||||||
sp_param_mode_t mode)
|
sp_param_mode_t mode)
|
||||||
{
|
{
|
||||||
sp_pvar_t *p= (sp_pvar_t *)sql_alloc(sizeof(sp_pvar_t));
|
sp_pvar_t *p= (sp_pvar_t *)sql_alloc(sizeof(sp_pvar_t));
|
||||||
|
|
||||||
if (p)
|
if (!p)
|
||||||
{
|
return NULL;
|
||||||
if (m_pvar.elements == m_psubsize)
|
|
||||||
m_psubsize+= 1;
|
++m_total_pvars;
|
||||||
p->name.str= name->str;
|
|
||||||
p->name.length= name->length;
|
p->name.str= name->str;
|
||||||
p->type= type;
|
p->name.length= name->length;
|
||||||
p->mode= mode;
|
p->type= type;
|
||||||
p->offset= current_pvars();
|
p->mode= mode;
|
||||||
p->dflt= NULL;
|
p->offset= current_pvars();
|
||||||
insert_dynamic(&m_pvar, (gptr)&p);
|
p->dflt= NULL;
|
||||||
}
|
insert_dynamic(&m_pvar, (gptr)&p);
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sp_label_t *
|
sp_label_t *
|
||||||
sp_pcontext::push_label(char *name, uint ip)
|
sp_pcontext::push_label(char *name, uint ip)
|
||||||
{
|
{
|
||||||
|
@ -354,6 +366,29 @@ sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
sp_pcontext::retrieve_field_definitions(List<create_field> *field_def_lst)
|
||||||
|
{
|
||||||
|
/* Put local/context fields in the result list. */
|
||||||
|
|
||||||
|
for (uint i = 0; i < m_pvar.elements; ++i)
|
||||||
|
{
|
||||||
|
sp_pvar_t *var_def;
|
||||||
|
get_dynamic(&m_pvar, (gptr) &var_def, i);
|
||||||
|
|
||||||
|
field_def_lst->push_back(&var_def->field_def);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put the fields of the enclosed contexts in the result list. */
|
||||||
|
|
||||||
|
List_iterator_fast<sp_pcontext> li(m_children);
|
||||||
|
sp_pcontext *ctx;
|
||||||
|
|
||||||
|
while ((ctx = li++))
|
||||||
|
ctx->retrieve_field_definitions(field_def_lst);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Find a cursor by offset from the top.
|
Find a cursor by offset from the top.
|
||||||
This is only used for debugging.
|
This is only used for debugging.
|
||||||
|
|
|
@ -34,8 +34,16 @@ typedef struct sp_pvar
|
||||||
LEX_STRING name;
|
LEX_STRING name;
|
||||||
enum enum_field_types type;
|
enum enum_field_types type;
|
||||||
sp_param_mode_t mode;
|
sp_param_mode_t mode;
|
||||||
uint offset; // Offset in current frame
|
|
||||||
|
/*
|
||||||
|
offset -- basically, this is an index of variable in the scope of root
|
||||||
|
parsing context. This means, that all variables in a stored routine
|
||||||
|
have distinct indexes/offsets.
|
||||||
|
*/
|
||||||
|
uint offset;
|
||||||
|
|
||||||
Item *dflt;
|
Item *dflt;
|
||||||
|
create_field field_def;
|
||||||
} sp_pvar_t;
|
} sp_pvar_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,9 +122,9 @@ class sp_pcontext : public Sql_alloc
|
||||||
//
|
//
|
||||||
|
|
||||||
inline uint
|
inline uint
|
||||||
max_pvars()
|
total_pvars()
|
||||||
{
|
{
|
||||||
return m_psubsize + m_pvar.elements;
|
return m_total_pvars;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint
|
inline uint
|
||||||
|
@ -155,16 +163,15 @@ class sp_pcontext : public Sql_alloc
|
||||||
p->dflt= it;
|
p->dflt= it;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
sp_pvar_t *
|
||||||
push_pvar(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode);
|
push_pvar(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode);
|
||||||
|
|
||||||
// Pop the last 'num' slots of the frame
|
/*
|
||||||
inline void
|
Retrieve definitions of fields from the current context and its
|
||||||
pop_pvar(uint num = 1)
|
children.
|
||||||
{
|
*/
|
||||||
while (num--)
|
void
|
||||||
pop_dynamic(&m_pvar);
|
retrieve_field_definitions(List<create_field> *field_def_lst);
|
||||||
}
|
|
||||||
|
|
||||||
// Find by name
|
// Find by name
|
||||||
sp_pvar_t *
|
sp_pvar_t *
|
||||||
|
@ -175,7 +182,7 @@ class sp_pcontext : public Sql_alloc
|
||||||
find_pvar(uint offset);
|
find_pvar(uint offset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set the current scope boundary (for default values)
|
Set the current scope boundary (for default values).
|
||||||
The argument is the number of variables to skip.
|
The argument is the number of variables to skip.
|
||||||
*/
|
*/
|
||||||
inline void
|
inline void
|
||||||
|
@ -184,6 +191,45 @@ class sp_pcontext : public Sql_alloc
|
||||||
m_pboundary= n;
|
m_pboundary= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
CASE expressions support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline int
|
||||||
|
register_case_expr()
|
||||||
|
{
|
||||||
|
return m_num_case_exprs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
get_num_case_exprs() const
|
||||||
|
{
|
||||||
|
return m_num_case_exprs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
push_case_expr_id(int case_expr_id)
|
||||||
|
{
|
||||||
|
return insert_dynamic(&m_case_expr_id_lst, (gptr) &case_expr_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
pop_case_expr_id()
|
||||||
|
{
|
||||||
|
pop_dynamic(&m_case_expr_id_lst);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
get_current_case_expr_id() const
|
||||||
|
{
|
||||||
|
int case_expr_id;
|
||||||
|
|
||||||
|
get_dynamic((DYNAMIC_ARRAY*)&m_case_expr_id_lst, (gptr) &case_expr_id,
|
||||||
|
m_case_expr_id_lst.elements - 1);
|
||||||
|
|
||||||
|
return case_expr_id;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Labels
|
// Labels
|
||||||
//
|
//
|
||||||
|
@ -280,8 +326,18 @@ class sp_pcontext : public Sql_alloc
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/*
|
||||||
|
m_total_pvars -- number of variables (including all types of arguments)
|
||||||
|
in this context including all children contexts.
|
||||||
|
|
||||||
|
m_total_pvars >= m_pvar.elements.
|
||||||
|
|
||||||
|
m_total_pvars of the root parsing context contains number of all
|
||||||
|
variables (including arguments) in all enclosed contexts.
|
||||||
|
*/
|
||||||
|
uint m_total_pvars;
|
||||||
|
|
||||||
// The maximum sub context's framesizes
|
// The maximum sub context's framesizes
|
||||||
uint m_psubsize;
|
|
||||||
uint m_csubsize;
|
uint m_csubsize;
|
||||||
uint m_hsubsize;
|
uint m_hsubsize;
|
||||||
uint m_handlers; // No. of handlers in this context
|
uint m_handlers; // No. of handlers in this context
|
||||||
|
@ -290,8 +346,19 @@ private:
|
||||||
|
|
||||||
sp_pcontext *m_parent; // Parent context
|
sp_pcontext *m_parent; // Parent context
|
||||||
|
|
||||||
uint m_poffset; // Variable offset for this context
|
/*
|
||||||
|
m_poffset -- basically, this is an index of the first variable in this
|
||||||
|
parsing context.
|
||||||
|
|
||||||
|
m_poffset is 0 for root context.
|
||||||
|
|
||||||
|
Since now each variable is stored in separate place, no reuse is done,
|
||||||
|
so m_poffset is different for all enclosed contexts.
|
||||||
|
*/
|
||||||
|
uint m_poffset;
|
||||||
|
|
||||||
uint m_coffset; // Cursor offset for this context
|
uint m_coffset; // Cursor offset for this context
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Boundary for finding variables in this context. This is the number
|
Boundary for finding variables in this context. This is the number
|
||||||
of variables currently "invisible" to default clauses.
|
of variables currently "invisible" to default clauses.
|
||||||
|
@ -300,7 +367,10 @@ private:
|
||||||
*/
|
*/
|
||||||
uint m_pboundary;
|
uint m_pboundary;
|
||||||
|
|
||||||
|
int m_num_case_exprs;
|
||||||
|
|
||||||
DYNAMIC_ARRAY m_pvar; // Parameters/variables
|
DYNAMIC_ARRAY m_pvar; // Parameters/variables
|
||||||
|
DYNAMIC_ARRAY m_case_expr_id_lst; /* Stack of CASE expression ids. */
|
||||||
DYNAMIC_ARRAY m_cond; // Conditions
|
DYNAMIC_ARRAY m_cond; // Conditions
|
||||||
DYNAMIC_ARRAY m_cursor; // Cursors
|
DYNAMIC_ARRAY m_cursor; // Cursors
|
||||||
DYNAMIC_ARRAY m_handler; // Handlers, for checking of duplicates
|
DYNAMIC_ARRAY m_handler; // Handlers, for checking of duplicates
|
||||||
|
|
|
@ -29,41 +29,137 @@
|
||||||
#include "sp_rcontext.h"
|
#include "sp_rcontext.h"
|
||||||
#include "sp_pcontext.h"
|
#include "sp_pcontext.h"
|
||||||
|
|
||||||
sp_rcontext::sp_rcontext(sp_rcontext *prev, uint fsize, uint hmax, uint cmax)
|
|
||||||
: m_count(0), m_fsize(fsize), m_result(NULL), m_hcount(0), m_hsp(0),
|
sp_rcontext::sp_rcontext(sp_pcontext *root_parsing_ctx,
|
||||||
m_ihsp(0), m_hfound(-1), m_ccount(0), m_prev_ctx(prev)
|
Field *return_value_fld,
|
||||||
|
sp_rcontext *prev_runtime_ctx)
|
||||||
|
:m_root_parsing_ctx(root_parsing_ctx),
|
||||||
|
m_var_table(0),
|
||||||
|
m_var_items(0),
|
||||||
|
m_return_value_fld(return_value_fld),
|
||||||
|
m_return_value_set(FALSE),
|
||||||
|
m_hcount(0),
|
||||||
|
m_hsp(0),
|
||||||
|
m_ihsp(0),
|
||||||
|
m_hfound(-1),
|
||||||
|
m_ccount(0),
|
||||||
|
m_case_expr_holders(0),
|
||||||
|
m_prev_runtime_ctx(prev_runtime_ctx)
|
||||||
{
|
{
|
||||||
m_frame= (Item **)sql_alloc(fsize * sizeof(Item*));
|
|
||||||
m_handler= (sp_handler_t *)sql_alloc(hmax * sizeof(sp_handler_t));
|
|
||||||
m_hstack= (uint *)sql_alloc(hmax * sizeof(uint));
|
|
||||||
m_in_handler= (uint *)sql_alloc(hmax * sizeof(uint));
|
|
||||||
m_cstack= (sp_cursor **)sql_alloc(cmax * sizeof(sp_cursor *));
|
|
||||||
m_saved.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
sp_rcontext::~sp_rcontext()
|
||||||
sp_rcontext::set_item_eval(THD *thd, uint idx, Item **item_addr,
|
|
||||||
enum_field_types type)
|
|
||||||
{
|
{
|
||||||
Item *it;
|
if (m_var_table)
|
||||||
Item *reuse_it;
|
free_blobs(m_var_table);
|
||||||
/* sp_eval_func_item will use callers_arena */
|
}
|
||||||
int res;
|
|
||||||
|
|
||||||
reuse_it= get_item(idx);
|
|
||||||
it= sp_eval_func_item(thd, item_addr, type, reuse_it, TRUE);
|
/*
|
||||||
if (! it)
|
Initialize sp_rcontext instance.
|
||||||
res= -1;
|
|
||||||
else
|
SYNOPSIS
|
||||||
|
thd Thread handle
|
||||||
|
RETURN
|
||||||
|
FALSE on success
|
||||||
|
TRUE on error
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool sp_rcontext::init(THD *thd)
|
||||||
|
{
|
||||||
|
if (init_var_table(thd) || init_var_items())
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return
|
||||||
|
!(m_handler=
|
||||||
|
(sp_handler_t*)thd->alloc(m_root_parsing_ctx->max_handlers() *
|
||||||
|
sizeof(sp_handler_t))) ||
|
||||||
|
!(m_hstack=
|
||||||
|
(uint*)thd->alloc(m_root_parsing_ctx->max_handlers() *
|
||||||
|
sizeof(uint))) ||
|
||||||
|
!(m_in_handler=
|
||||||
|
(uint*)thd->alloc(m_root_parsing_ctx->max_handlers() *
|
||||||
|
sizeof(uint))) ||
|
||||||
|
!(m_cstack=
|
||||||
|
(sp_cursor**)thd->alloc(m_root_parsing_ctx->max_cursors() *
|
||||||
|
sizeof(sp_cursor*))) ||
|
||||||
|
!(m_case_expr_holders=
|
||||||
|
(Item_cache**)thd->calloc(m_root_parsing_ctx->get_num_case_exprs() *
|
||||||
|
sizeof (Item_cache*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create and initialize a table to store SP-vars.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
thd Thread handler.
|
||||||
|
RETURN
|
||||||
|
FALSE on success
|
||||||
|
TRUE on error
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
sp_rcontext::init_var_table(THD *thd)
|
||||||
|
{
|
||||||
|
List<create_field> field_def_lst;
|
||||||
|
|
||||||
|
if (!m_root_parsing_ctx->total_pvars())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
m_root_parsing_ctx->retrieve_field_definitions(&field_def_lst);
|
||||||
|
|
||||||
|
DBUG_ASSERT(field_def_lst.elements == m_root_parsing_ctx->total_pvars());
|
||||||
|
|
||||||
|
if (!(m_var_table= create_virtual_tmp_table(thd, field_def_lst)))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
m_var_table->copy_blobs= TRUE;
|
||||||
|
m_var_table->alias= "";
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create and initialize an Item-adapter (Item_field) for each SP-var field.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
FALSE on success
|
||||||
|
TRUE on error
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
sp_rcontext::init_var_items()
|
||||||
|
{
|
||||||
|
uint idx;
|
||||||
|
uint num_vars= m_root_parsing_ctx->total_pvars();
|
||||||
|
|
||||||
|
if (!(m_var_items= (Item**) sql_alloc(num_vars * sizeof (Item *))))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (idx = 0; idx < num_vars; ++idx)
|
||||||
{
|
{
|
||||||
res= 0;
|
if (!(m_var_items[idx]= new Item_field(m_var_table->field[idx])))
|
||||||
set_item(idx, it);
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
sp_rcontext::set_return_value(THD *thd, Item *return_value_item)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(m_return_value_fld);
|
||||||
|
|
||||||
|
m_return_value_set = TRUE;
|
||||||
|
|
||||||
|
return sp_eval_expr(thd, m_return_value_fld, return_value_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sp_rcontext::find_handler(uint sql_errno,
|
sp_rcontext::find_handler(uint sql_errno,
|
||||||
MYSQL_ERROR::enum_warning_level level)
|
MYSQL_ERROR::enum_warning_level level)
|
||||||
|
@ -117,32 +213,14 @@ sp_rcontext::find_handler(uint sql_errno,
|
||||||
}
|
}
|
||||||
if (found < 0)
|
if (found < 0)
|
||||||
{
|
{
|
||||||
if (m_prev_ctx)
|
if (m_prev_runtime_ctx)
|
||||||
return m_prev_ctx->find_handler(sql_errno, level);
|
return m_prev_runtime_ctx->find_handler(sql_errno, level);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
m_hfound= found;
|
m_hfound= found;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
sp_rcontext::save_variables(uint fp)
|
|
||||||
{
|
|
||||||
while (fp < m_count)
|
|
||||||
{
|
|
||||||
m_saved.push_front(m_frame[fp]);
|
|
||||||
m_frame[fp++]= NULL; // Prevent reuse
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sp_rcontext::restore_variables(uint fp)
|
|
||||||
{
|
|
||||||
uint i= m_count;
|
|
||||||
|
|
||||||
while (i-- > fp)
|
|
||||||
m_frame[i]= m_saved.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
|
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
|
||||||
|
@ -150,6 +228,7 @@ sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
|
||||||
m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i);
|
m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sp_rcontext::pop_cursors(uint count)
|
sp_rcontext::pop_cursors(uint count)
|
||||||
{
|
{
|
||||||
|
@ -160,6 +239,40 @@ sp_rcontext::pop_cursors(uint count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
sp_rcontext::set_variable(THD *thd, uint var_idx, Item *value)
|
||||||
|
{
|
||||||
|
return set_variable(thd, m_var_table->field[var_idx], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
sp_rcontext::set_variable(THD *thd, Field *field, Item *value)
|
||||||
|
{
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
field->set_null();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sp_eval_expr(thd, field, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *
|
||||||
|
sp_rcontext::get_item(uint var_idx)
|
||||||
|
{
|
||||||
|
return m_var_items[var_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item **
|
||||||
|
sp_rcontext::get_item_addr(uint var_idx)
|
||||||
|
{
|
||||||
|
return m_var_items + var_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* sp_cursor
|
* sp_cursor
|
||||||
|
@ -263,6 +376,102 @@ sp_cursor::fetch(THD *thd, List<struct sp_pvar> *vars)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create an instance of appropriate Item_cache class depending on the
|
||||||
|
specified type in the callers arena.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
thd thread handler
|
||||||
|
result_type type of the expression
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
Pointer to valid object on success
|
||||||
|
NULL on error
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
We should create cache items in the callers arena, as they are used
|
||||||
|
between in several instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Item_cache *
|
||||||
|
sp_rcontext::create_case_expr_holder(THD *thd, Item_result result_type)
|
||||||
|
{
|
||||||
|
Item_cache *holder;
|
||||||
|
Query_arena current_arena;
|
||||||
|
|
||||||
|
thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena);
|
||||||
|
|
||||||
|
holder= Item_cache::get_cache(result_type);
|
||||||
|
|
||||||
|
thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena);
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set CASE expression to the specified value.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
thd thread handler
|
||||||
|
case_expr_id identifier of the CASE expression
|
||||||
|
case_expr_item a value of the CASE expression
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
FALSE on success
|
||||||
|
TRUE on error
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
The idea is to reuse Item_cache for the expression of the one CASE
|
||||||
|
statement. This optimization takes place when there is CASE statement
|
||||||
|
inside of a loop. So, in other words, we will use the same object on each
|
||||||
|
iteration instead of creating a new one for each iteration.
|
||||||
|
|
||||||
|
TODO
|
||||||
|
Hypothetically, a type of CASE expression can be different for each
|
||||||
|
iteration. For instance, this can happen if the expression contains a
|
||||||
|
session variable (something like @@VAR) and its type is changed from one
|
||||||
|
iteration to another.
|
||||||
|
|
||||||
|
In order to cope with this problem, we check type each time, when we use
|
||||||
|
already created object. If the type does not match, we re-create Item.
|
||||||
|
This also can (should?) be optimized.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item *case_expr_item)
|
||||||
|
{
|
||||||
|
if (!(case_expr_item= sp_prepare_func_item(thd, &case_expr_item)))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!m_case_expr_holders[case_expr_id] ||
|
||||||
|
m_case_expr_holders[case_expr_id]->result_type() !=
|
||||||
|
case_expr_item->result_type())
|
||||||
|
{
|
||||||
|
m_case_expr_holders[case_expr_id]=
|
||||||
|
create_case_expr_holder(thd, case_expr_item->result_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_case_expr_holders[case_expr_id]->store(case_expr_item);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *
|
||||||
|
sp_rcontext::get_case_expr(int case_expr_id)
|
||||||
|
{
|
||||||
|
return m_case_expr_holders[case_expr_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item **
|
||||||
|
sp_rcontext::get_case_expr_addr(int case_expr_id)
|
||||||
|
{
|
||||||
|
return (Item**) m_case_expr_holders + case_expr_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Select_fetch_into_spvars
|
Select_fetch_into_spvars
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -294,11 +503,8 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items)
|
||||||
*/
|
*/
|
||||||
for (; pv= pv_iter++, item= item_iter++; )
|
for (; pv= pv_iter++, item= item_iter++; )
|
||||||
{
|
{
|
||||||
Item *reuse= thd->spcont->get_item(pv->offset);
|
if (thd->spcont->set_variable(thd, pv->offset, item))
|
||||||
/* Evaluate a new item on the arena of the calling instruction */
|
return TRUE;
|
||||||
Item *it= sp_eval_func_item(thd, &item, pv->type, reuse, TRUE);
|
|
||||||
|
|
||||||
thd->spcont->set_item(pv->offset, it);
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,22 @@ typedef struct
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is a run context? of one SP ?
|
This class is a runtime context of a Stored Routine. It is used in an
|
||||||
THis is
|
execution and is intended to contain all dynamic objects (i.e. objects, which
|
||||||
- a stack of cursors?
|
can be changed during execution), such as:
|
||||||
- a stack of handlers?
|
- stored routine variables;
|
||||||
- a stack of Items ?
|
- cursors;
|
||||||
- a stack of instruction locations in SP?
|
- handlers;
|
||||||
|
|
||||||
|
Runtime context is used with sp_head class. sp_head class is intended to
|
||||||
|
contain all static things, related to the stored routines (code, for example).
|
||||||
|
sp_head instance creates runtime context for the execution of a stored
|
||||||
|
routine.
|
||||||
|
|
||||||
|
There is a parsing context (an instance of sp_pcontext class), which is used
|
||||||
|
on parsing stage. However, now it contains some necessary for an execution
|
||||||
|
things, such as definition of used stored routine variables. That's why
|
||||||
|
runtime context needs a reference to the parsing context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class sp_rcontext : public Sql_alloc
|
class sp_rcontext : public Sql_alloc
|
||||||
|
@ -68,62 +78,34 @@ class sp_rcontext : public Sql_alloc
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
/*
|
/*
|
||||||
Routine to which this Item_splocal belongs. Used for checking if correct
|
The routine for which this runtime context is created. Used for checking
|
||||||
runtime context is used for variable handling.
|
if correct runtime context is used for variable handling.
|
||||||
*/
|
*/
|
||||||
sp_head *owner;
|
sp_head *sp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sp_rcontext(sp_rcontext *prev, uint fsize, uint hmax, uint cmax);
|
sp_rcontext(sp_pcontext *root_parsing_ctx, Field *return_value_fld,
|
||||||
|
sp_rcontext *prev_runtime_ctx);
|
||||||
|
bool init(THD *thd);
|
||||||
|
|
||||||
~sp_rcontext()
|
~sp_rcontext();
|
||||||
{
|
|
||||||
// Not needed?
|
|
||||||
//sql_element_free(m_frame);
|
|
||||||
//m_saved.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
push_item(Item *i)
|
|
||||||
{
|
|
||||||
if (m_count < m_fsize)
|
|
||||||
m_frame[m_count++]= i;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
set_item(uint idx, Item *i)
|
|
||||||
{
|
|
||||||
if (idx < m_count)
|
|
||||||
m_frame[idx]= i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns 0 on success, -1 on (eval) failure */
|
|
||||||
int
|
int
|
||||||
set_item_eval(THD *thd, uint idx, Item **i, enum_field_types type);
|
set_variable(THD *thd, uint var_idx, Item *value);
|
||||||
|
|
||||||
inline Item *
|
Item *
|
||||||
get_item(uint idx)
|
get_item(uint var_idx);
|
||||||
|
|
||||||
|
Item **
|
||||||
|
get_item_addr(uint var_idx);
|
||||||
|
|
||||||
|
bool
|
||||||
|
set_return_value(THD *thd, Item *return_value_item);
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
is_return_value_set() const
|
||||||
{
|
{
|
||||||
return m_frame[idx];
|
return m_return_value_set;
|
||||||
}
|
|
||||||
|
|
||||||
inline Item **
|
|
||||||
get_item_addr(uint idx)
|
|
||||||
{
|
|
||||||
return m_frame + idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void
|
|
||||||
set_result(Item *it)
|
|
||||||
{
|
|
||||||
m_result= it;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Item *
|
|
||||||
get_result()
|
|
||||||
{
|
|
||||||
return m_result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -195,14 +177,6 @@ class sp_rcontext : public Sql_alloc
|
||||||
m_ihsp-= 1;
|
m_ihsp-= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save variables starting at fp and up
|
|
||||||
void
|
|
||||||
save_variables(uint fp);
|
|
||||||
|
|
||||||
// Restore variables down to fp
|
|
||||||
void
|
|
||||||
restore_variables(uint fp);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);
|
push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);
|
||||||
|
|
||||||
|
@ -221,13 +195,42 @@ class sp_rcontext : public Sql_alloc
|
||||||
return m_cstack[i];
|
return m_cstack[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
CASE expressions support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
set_case_expr(THD *thd, int case_expr_id, Item *case_expr_item);
|
||||||
|
|
||||||
|
Item *
|
||||||
|
get_case_expr(int case_expr_id);
|
||||||
|
|
||||||
|
Item **
|
||||||
|
get_case_expr_addr(int case_expr_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
sp_pcontext *m_root_parsing_ctx;
|
||||||
|
|
||||||
uint m_count;
|
/* Virtual table for storing variables. */
|
||||||
uint m_fsize;
|
TABLE *m_var_table;
|
||||||
Item **m_frame;
|
|
||||||
|
|
||||||
Item *m_result; // For FUNCTIONs
|
/*
|
||||||
|
Collection of Item_field proxies, each of them points to the corresponding
|
||||||
|
field in m_var_table.
|
||||||
|
*/
|
||||||
|
Item **m_var_items;
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is a pointer to a field, which should contain return value for stored
|
||||||
|
functions (only). For stored procedures, this pointer is NULL.
|
||||||
|
*/
|
||||||
|
Field *m_return_value_fld;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Indicates whether the return value (in m_return_value_fld) has been set
|
||||||
|
during execution.
|
||||||
|
*/
|
||||||
|
bool m_return_value_set;
|
||||||
|
|
||||||
sp_handler_t *m_handler; // Visible handlers
|
sp_handler_t *m_handler; // Visible handlers
|
||||||
uint m_hcount; // Stack pointer for m_handler
|
uint m_hcount; // Stack pointer for m_handler
|
||||||
|
@ -236,13 +239,22 @@ private:
|
||||||
uint *m_in_handler; // Active handler, for recursion check
|
uint *m_in_handler; // Active handler, for recursion check
|
||||||
uint m_ihsp; // Stack pointer for m_in_handler
|
uint m_ihsp; // Stack pointer for m_in_handler
|
||||||
int m_hfound; // Set by find_handler; -1 if not found
|
int m_hfound; // Set by find_handler; -1 if not found
|
||||||
List<Item> m_saved; // Saved variables during handler exec.
|
|
||||||
|
|
||||||
sp_cursor **m_cstack;
|
sp_cursor **m_cstack;
|
||||||
uint m_ccount;
|
uint m_ccount;
|
||||||
|
|
||||||
sp_rcontext *m_prev_ctx; // Previous context (NULL if none)
|
Item_cache **m_case_expr_holders;
|
||||||
|
|
||||||
|
/* Previous runtime context (NULL if none) */
|
||||||
|
sp_rcontext *m_prev_runtime_ctx;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool init_var_table(THD *thd);
|
||||||
|
bool init_var_items();
|
||||||
|
|
||||||
|
Item_cache *create_case_expr_holder(THD *thd, Item_result result_type);
|
||||||
|
|
||||||
|
int set_variable(THD *thd, Field *field, Item *value);
|
||||||
}; // class sp_rcontext : public Sql_alloc
|
}; // class sp_rcontext : public Sql_alloc
|
||||||
|
|
||||||
|
|
||||||
|
|
106
sql/sql_acl.cc
106
sql/sql_acl.cc
|
@ -2760,8 +2760,9 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
||||||
uint unused_field_idx= NO_CACHED_FIELD_INDEX;
|
uint unused_field_idx= NO_CACHED_FIELD_INDEX;
|
||||||
TABLE_LIST *dummy;
|
TABLE_LIST *dummy;
|
||||||
Field *f=find_field_in_table_ref(thd, table_list, column->column.ptr(),
|
Field *f=find_field_in_table_ref(thd, table_list, column->column.ptr(),
|
||||||
|
column->column.length(),
|
||||||
column->column.ptr(), NULL, NULL,
|
column->column.ptr(), NULL, NULL,
|
||||||
column->column.length(), 0, 1, 1, 0,
|
NULL, TRUE, FALSE,
|
||||||
&unused_field_idx, FALSE, &dummy);
|
&unused_field_idx, FALSE, &dummy);
|
||||||
if (f == (Field*)0)
|
if (f == (Field*)0)
|
||||||
{
|
{
|
||||||
|
@ -3616,11 +3617,28 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check column rights in given security context
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_grant_column()
|
||||||
|
thd thread handler
|
||||||
|
grant grant information structure
|
||||||
|
db_name db name
|
||||||
|
table_name table name
|
||||||
|
name column name
|
||||||
|
length column name length
|
||||||
|
sctx security context
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
FALSE OK
|
||||||
|
TRUE access denied
|
||||||
|
*/
|
||||||
|
|
||||||
bool check_grant_column(THD *thd, GRANT_INFO *grant,
|
bool check_grant_column(THD *thd, GRANT_INFO *grant,
|
||||||
const char *db_name, const char *table_name,
|
const char *db_name, const char *table_name,
|
||||||
const char *name, uint length, uint show_tables)
|
const char *name, uint length, Security_context *sctx)
|
||||||
{
|
{
|
||||||
Security_context *sctx= thd->security_ctx;
|
|
||||||
GRANT_TABLE *grant_table;
|
GRANT_TABLE *grant_table;
|
||||||
GRANT_COLUMN *grant_column;
|
GRANT_COLUMN *grant_column;
|
||||||
ulong want_access= grant->want_privilege & ~grant->privilege;
|
ulong want_access= grant->want_privilege & ~grant->privilege;
|
||||||
|
@ -3651,31 +3669,77 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
|
||||||
rw_unlock(&LOCK_grant);
|
rw_unlock(&LOCK_grant);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
#ifdef NOT_USED
|
|
||||||
if (show_tables && (grant_column || grant->privilege & COL_ACLS))
|
|
||||||
{
|
|
||||||
rw_unlock(&LOCK_grant); /* purecov: deadcode */
|
|
||||||
DBUG_RETURN(0); /* purecov: deadcode */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
rw_unlock(&LOCK_grant);
|
rw_unlock(&LOCK_grant);
|
||||||
if (!show_tables)
|
char command[128];
|
||||||
{
|
get_privilege_desc(command, sizeof(command), want_access);
|
||||||
char command[128];
|
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
|
||||||
get_privilege_desc(command, sizeof(command), want_access);
|
command,
|
||||||
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
|
sctx->priv_user,
|
||||||
command,
|
sctx->host_or_ip,
|
||||||
sctx->priv_user,
|
name,
|
||||||
sctx->host_or_ip,
|
table_name);
|
||||||
name,
|
|
||||||
table_name);
|
|
||||||
}
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check the access right to a column depending on the type of table.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_column_grant_in_table_ref()
|
||||||
|
thd thread handler
|
||||||
|
table_ref table reference where to check the field
|
||||||
|
name name of field to check
|
||||||
|
length length of name
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Check the access rights to a column depending on the type of table
|
||||||
|
reference where the column is checked. The function provides a
|
||||||
|
generic interface to check column access rights that hides the
|
||||||
|
heterogeneity of the column representation - whether it is a view
|
||||||
|
or a stored table colum.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
FALSE OK
|
||||||
|
TRUE access denied
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
|
||||||
|
const char *name, uint length)
|
||||||
|
{
|
||||||
|
GRANT_INFO *grant;
|
||||||
|
const char *db_name;
|
||||||
|
const char *table_name;
|
||||||
|
Security_context *sctx= test(table_ref->security_ctx) ?
|
||||||
|
table_ref->security_ctx : thd->security_ctx;
|
||||||
|
|
||||||
|
if (table_ref->view || table_ref->field_translation)
|
||||||
|
{
|
||||||
|
/* View or derived information schema table. */
|
||||||
|
grant= &(table_ref->grant);
|
||||||
|
db_name= table_ref->view_db.str;
|
||||||
|
table_name= table_ref->view_name.str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Normal or temporary table. */
|
||||||
|
TABLE *table= table_ref->table;
|
||||||
|
grant= &(table->grant);
|
||||||
|
db_name= table->s->db.str;
|
||||||
|
table_name= table->s->table_name.str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grant->want_privilege)
|
||||||
|
return check_grant_column(thd, grant, db_name, table_name, name,
|
||||||
|
length, sctx);
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
|
bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
|
||||||
const char* db_name, const char *table_name,
|
const char* db_name, const char *table_name,
|
||||||
Field_iterator *fields)
|
Field_iterator *fields)
|
||||||
|
|
|
@ -205,7 +205,9 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
||||||
uint show_command, uint number, bool dont_print_error);
|
uint show_command, uint number, bool dont_print_error);
|
||||||
bool check_grant_column (THD *thd, GRANT_INFO *grant,
|
bool check_grant_column (THD *thd, GRANT_INFO *grant,
|
||||||
const char *db_name, const char *table_name,
|
const char *db_name, const char *table_name,
|
||||||
const char *name, uint length, uint show_command=0);
|
const char *name, uint length, Security_context *sctx);
|
||||||
|
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
|
||||||
|
const char *name, uint length);
|
||||||
bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
|
bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
|
||||||
const char* db_name, const char *table_name,
|
const char* db_name, const char *table_name,
|
||||||
Field_iterator *fields);
|
Field_iterator *fields);
|
||||||
|
|
255
sql/sql_base.cc
255
sql/sql_base.cc
|
@ -2616,15 +2616,25 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||||
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
|
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
|
||||||
thd->lex->sroutines_list.elements)
|
thd->lex->sroutines_list.elements)
|
||||||
{
|
{
|
||||||
bool first_no_prelocking, need_prelocking;
|
bool first_no_prelocking, need_prelocking, tabs_changed;
|
||||||
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
|
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
|
||||||
|
|
||||||
DBUG_ASSERT(thd->lex->query_tables == *start);
|
DBUG_ASSERT(thd->lex->query_tables == *start);
|
||||||
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
|
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
|
||||||
|
|
||||||
if ((sp_cache_routines_and_add_tables(thd, thd->lex,
|
if (sp_cache_routines_and_add_tables(thd, thd->lex,
|
||||||
first_no_prelocking) ||
|
first_no_prelocking,
|
||||||
*start) && need_prelocking)
|
&tabs_changed))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else if ((tabs_changed || *start) && need_prelocking)
|
||||||
{
|
{
|
||||||
query_tables_last_own= save_query_tables_last;
|
query_tables_last_own= save_query_tables_last;
|
||||||
*start= thd->lex->query_tables;
|
*start= thd->lex->query_tables;
|
||||||
|
@ -2748,9 +2758,18 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||||
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
|
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||||
{
|
{
|
||||||
if (!query_tables_last_own)
|
if (!query_tables_last_own)
|
||||||
query_tables_last_own= thd->lex->query_tables_last;
|
query_tables_last_own= thd->lex->query_tables_last;
|
||||||
sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
|
if (sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
|
||||||
tables->table->triggers);
|
tables->table->triggers))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
||||||
}
|
}
|
||||||
|
@ -2771,9 +2790,21 @@ process_view_routines:
|
||||||
/* We have at least one table in TL here. */
|
/* We have at least one table in TL here. */
|
||||||
if (!query_tables_last_own)
|
if (!query_tables_last_own)
|
||||||
query_tables_last_own= thd->lex->query_tables_last;
|
query_tables_last_own= thd->lex->query_tables_last;
|
||||||
sp_cache_routines_and_add_tables_for_view(thd, thd->lex, tables->view);
|
if (sp_cache_routines_and_add_tables_for_view(thd, thd->lex,
|
||||||
|
tables->view))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
thd->proc_info=0;
|
thd->proc_info=0;
|
||||||
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
|
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
|
||||||
|
|
||||||
|
@ -3337,47 +3368,6 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
/*
|
|
||||||
Check column rights in given security context
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
check_grant_column_in_sctx()
|
|
||||||
thd thread handler
|
|
||||||
grant grant information structure
|
|
||||||
db db name
|
|
||||||
table table name
|
|
||||||
name column name
|
|
||||||
length column name length
|
|
||||||
check_grants need to check grants
|
|
||||||
sctx 0 or security context
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
FALSE OK
|
|
||||||
TRUE access denied
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
|
|
||||||
const char *db, const char *table,
|
|
||||||
const char *name, uint length,
|
|
||||||
bool check_grants,
|
|
||||||
Security_context *sctx)
|
|
||||||
{
|
|
||||||
if (!check_grants)
|
|
||||||
return FALSE;
|
|
||||||
Security_context *save_security_ctx= thd->security_ctx;
|
|
||||||
bool res;
|
|
||||||
if (sctx)
|
|
||||||
{
|
|
||||||
thd->security_ctx= sctx;
|
|
||||||
}
|
|
||||||
res= check_grant_column(thd, grant, db, table, name, length);
|
|
||||||
thd->security_ctx= save_security_ctx;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Find a field by name in a view that uses merge algorithm.
|
Find a field by name in a view that uses merge algorithm.
|
||||||
|
|
||||||
|
@ -3386,11 +3376,10 @@ static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
|
||||||
thd thread handler
|
thd thread handler
|
||||||
table_list view to search for 'name'
|
table_list view to search for 'name'
|
||||||
name name of field
|
name name of field
|
||||||
item_name name of item if it will be created (VIEW)
|
|
||||||
length length of name
|
length length of name
|
||||||
|
item_name name of item if it will be created (VIEW)
|
||||||
ref expression substituted in VIEW should be passed
|
ref expression substituted in VIEW should be passed
|
||||||
using this reference (return view_ref_found)
|
using this reference (return view_ref_found)
|
||||||
check_grants do check columns grants for view?
|
|
||||||
register_tree_change TRUE if ref is not stack variable and we
|
register_tree_change TRUE if ref is not stack variable and we
|
||||||
need register changes in item tree
|
need register changes in item tree
|
||||||
|
|
||||||
|
@ -3402,8 +3391,8 @@ static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
|
||||||
|
|
||||||
static Field *
|
static Field *
|
||||||
find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||||
const char *name, const char *item_name,
|
const char *name, uint length,
|
||||||
uint length, Item **ref, bool check_grants,
|
const char *item_name, Item **ref,
|
||||||
bool register_tree_change)
|
bool register_tree_change)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("find_field_in_view");
|
DBUG_ENTER("find_field_in_view");
|
||||||
|
@ -3420,24 +3409,13 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||||
{
|
{
|
||||||
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
|
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
|
||||||
{
|
{
|
||||||
if (table_list->schema_table_reformed)
|
|
||||||
/*
|
|
||||||
Translation table items are always Item_fields and fixed already
|
|
||||||
('mysql_schema_table' function). So we can return ->field. It is
|
|
||||||
used only for 'show & where' commands.
|
|
||||||
*/
|
|
||||||
DBUG_RETURN(((Item_field*) (field_it.item()))->field);
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
if (check_grant_column_in_sctx(thd, &table_list->grant,
|
|
||||||
table_list->view_db.str,
|
|
||||||
table_list->view_name.str, name, length,
|
|
||||||
check_grants,
|
|
||||||
table_list->security_ctx))
|
|
||||||
DBUG_RETURN(WRONG_GRANT);
|
|
||||||
#endif
|
|
||||||
// in PS use own arena or data will be freed after prepare
|
// in PS use own arena or data will be freed after prepare
|
||||||
if (register_tree_change)
|
if (register_tree_change)
|
||||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||||
|
/*
|
||||||
|
create_item() may, or may not create a new Item, depending on
|
||||||
|
the column reference. See create_view_field() for details.
|
||||||
|
*/
|
||||||
Item *item= field_it.create_item(thd);
|
Item *item= field_it.create_item(thd);
|
||||||
if (register_tree_change && arena)
|
if (register_tree_change && arena)
|
||||||
thd->restore_active_arena(arena, &backup);
|
thd->restore_active_arena(arena, &backup);
|
||||||
|
@ -3479,7 +3457,6 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||||
length [in] length of name
|
length [in] length of name
|
||||||
ref [in/out] if 'name' is resolved to a view field, ref is
|
ref [in/out] if 'name' is resolved to a view field, ref is
|
||||||
set to point to the found view field
|
set to point to the found view field
|
||||||
check_grants [in] do check columns grants?
|
|
||||||
register_tree_change [in] TRUE if ref is not stack variable and we
|
register_tree_change [in] TRUE if ref is not stack variable and we
|
||||||
need register changes in item tree
|
need register changes in item tree
|
||||||
actual_table [out] the original table reference where the field
|
actual_table [out] the original table reference where the field
|
||||||
|
@ -3500,8 +3477,7 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||||
|
|
||||||
static Field *
|
static Field *
|
||||||
find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||||
uint length, Item **ref, bool check_grants,
|
uint length, Item **ref, bool register_tree_change,
|
||||||
bool register_tree_change,
|
|
||||||
TABLE_LIST **actual_table)
|
TABLE_LIST **actual_table)
|
||||||
{
|
{
|
||||||
List_iterator_fast<Natural_join_column>
|
List_iterator_fast<Natural_join_column>
|
||||||
|
@ -3526,23 +3502,16 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
if (check_grants && nj_col->check_grants(thd, name, length))
|
|
||||||
DBUG_RETURN(WRONG_GRANT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (nj_col->view_field)
|
if (nj_col->view_field)
|
||||||
{
|
{
|
||||||
Item *item;
|
Item *item;
|
||||||
/*
|
|
||||||
The found field is a view field, we do as in find_field_in_view()
|
|
||||||
and return a pointer to pointer to the Item of that field.
|
|
||||||
*/
|
|
||||||
if (register_tree_change)
|
if (register_tree_change)
|
||||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||||
|
/*
|
||||||
|
create_item() may, or may not create a new Item, depending on the
|
||||||
|
column reference. See create_view_field() for details.
|
||||||
|
*/
|
||||||
item= nj_col->create_item(thd);
|
item= nj_col->create_item(thd);
|
||||||
|
|
||||||
if (register_tree_change && arena)
|
if (register_tree_change && arena)
|
||||||
thd->restore_active_arena(arena, &backup);
|
thd->restore_active_arena(arena, &backup);
|
||||||
|
|
||||||
|
@ -3588,7 +3557,6 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||||
table table where to search for the field
|
table table where to search for the field
|
||||||
name name of field
|
name name of field
|
||||||
length length of name
|
length length of name
|
||||||
check_grants do check columns grants?
|
|
||||||
allow_rowid do allow finding of "_rowid" field?
|
allow_rowid do allow finding of "_rowid" field?
|
||||||
cached_field_index_ptr cached position in field list (used to speedup
|
cached_field_index_ptr cached position in field list (used to speedup
|
||||||
lookup for fields in prepared tables)
|
lookup for fields in prepared tables)
|
||||||
|
@ -3600,9 +3568,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||||
|
|
||||||
Field *
|
Field *
|
||||||
find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
||||||
bool check_grants, bool allow_rowid,
|
bool allow_rowid, uint *cached_field_index_ptr)
|
||||||
uint *cached_field_index_ptr,
|
|
||||||
Security_context *sctx)
|
|
||||||
{
|
{
|
||||||
Field **field_ptr, *field;
|
Field **field_ptr, *field;
|
||||||
uint cached_field_index= *cached_field_index_ptr;
|
uint cached_field_index= *cached_field_index_ptr;
|
||||||
|
@ -3652,13 +3618,6 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
||||||
|
|
||||||
update_field_dependencies(thd, field, table);
|
update_field_dependencies(thd, field, table);
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
if (check_grant_column_in_sctx(thd, &table->grant,
|
|
||||||
table->s->db.str, table->s->table_name.str,
|
|
||||||
name, length,
|
|
||||||
check_grants, sctx))
|
|
||||||
field= WRONG_GRANT;
|
|
||||||
#endif
|
|
||||||
DBUG_RETURN(field);
|
DBUG_RETURN(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3671,14 +3630,13 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
||||||
thd [in] thread handler
|
thd [in] thread handler
|
||||||
table_list [in] table reference to search
|
table_list [in] table reference to search
|
||||||
name [in] name of field
|
name [in] name of field
|
||||||
item_name [in] name of item if it will be created (VIEW)
|
|
||||||
table_name [in] optional table name that qualifies the field
|
|
||||||
db_name [in] optional database name that qualifies the
|
|
||||||
length [in] field length of name
|
length [in] field length of name
|
||||||
|
item_name [in] name of item if it will be created (VIEW)
|
||||||
|
db_name [in] optional database name that qualifies the
|
||||||
|
table_name [in] optional table name that qualifies the field
|
||||||
ref [in/out] if 'name' is resolved to a view field, ref
|
ref [in/out] if 'name' is resolved to a view field, ref
|
||||||
is set to point to the found view field
|
is set to point to the found view field
|
||||||
check_grants_table [in] do check columns grants for table?
|
check_privileges [in] check privileges
|
||||||
check_grants_view [in] do check columns grants for view?
|
|
||||||
allow_rowid [in] do allow finding of "_rowid" field?
|
allow_rowid [in] do allow finding of "_rowid" field?
|
||||||
cached_field_index_ptr [in] cached position in field list (used to
|
cached_field_index_ptr [in] cached position in field list (used to
|
||||||
speedup lookup for fields in prepared tables)
|
speedup lookup for fields in prepared tables)
|
||||||
|
@ -3708,11 +3666,11 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
||||||
|
|
||||||
Field *
|
Field *
|
||||||
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||||
const char *name, const char *item_name,
|
const char *name, uint length,
|
||||||
const char *table_name, const char *db_name,
|
const char *item_name, const char *db_name,
|
||||||
uint length, Item **ref,
|
const char *table_name, Item **ref,
|
||||||
bool check_grants_table, bool check_grants_view,
|
bool check_privileges, bool allow_rowid,
|
||||||
bool allow_rowid, uint *cached_field_index_ptr,
|
uint *cached_field_index_ptr,
|
||||||
bool register_tree_change, TABLE_LIST **actual_table)
|
bool register_tree_change, TABLE_LIST **actual_table)
|
||||||
{
|
{
|
||||||
Field *fld;
|
Field *fld;
|
||||||
|
@ -3757,8 +3715,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||||
if (table_list->field_translation)
|
if (table_list->field_translation)
|
||||||
{
|
{
|
||||||
/* 'table_list' is a view or an information schema table. */
|
/* 'table_list' is a view or an information schema table. */
|
||||||
if ((fld= find_field_in_view(thd, table_list, name, item_name, length,
|
if ((fld= find_field_in_view(thd, table_list, name, length, item_name, ref,
|
||||||
ref, check_grants_view,
|
|
||||||
register_tree_change)))
|
register_tree_change)))
|
||||||
*actual_table= table_list;
|
*actual_table= table_list;
|
||||||
}
|
}
|
||||||
|
@ -3767,20 +3724,9 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||||
/* 'table_list' is a stored table. */
|
/* 'table_list' is a stored table. */
|
||||||
DBUG_ASSERT(table_list->table);
|
DBUG_ASSERT(table_list->table);
|
||||||
if ((fld= find_field_in_table(thd, table_list->table, name, length,
|
if ((fld= find_field_in_table(thd, table_list->table, name, length,
|
||||||
check_grants_table, allow_rowid,
|
allow_rowid,
|
||||||
cached_field_index_ptr,
|
cached_field_index_ptr)))
|
||||||
table_list->security_ctx)))
|
|
||||||
*actual_table= table_list;
|
*actual_table= table_list;
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
/* check for views with temporary table algorithm */
|
|
||||||
if (check_grants_view && table_list->view &&
|
|
||||||
fld && fld != WRONG_GRANT &&
|
|
||||||
check_grant_column(thd, &table_list->grant,
|
|
||||||
table_list->view_db.str,
|
|
||||||
table_list->view_name.str,
|
|
||||||
name, length))
|
|
||||||
fld= WRONG_GRANT;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3797,11 +3743,10 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||||
TABLE_LIST *table;
|
TABLE_LIST *table;
|
||||||
while ((table= it++))
|
while ((table= it++))
|
||||||
{
|
{
|
||||||
if ((fld= find_field_in_table_ref(thd, table, name, item_name,
|
if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
|
||||||
table_name, db_name, length, ref,
|
db_name, table_name, ref,
|
||||||
check_grants_table,
|
check_privileges, allow_rowid,
|
||||||
check_grants_view,
|
cached_field_index_ptr,
|
||||||
allow_rowid, cached_field_index_ptr,
|
|
||||||
register_tree_change, actual_table)))
|
register_tree_change, actual_table)))
|
||||||
DBUG_RETURN(fld);
|
DBUG_RETURN(fld);
|
||||||
}
|
}
|
||||||
|
@ -3814,11 +3759,16 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||||
directly the top-most NATURAL/USING join.
|
directly the top-most NATURAL/USING join.
|
||||||
*/
|
*/
|
||||||
fld= find_field_in_natural_join(thd, table_list, name, length, ref,
|
fld= find_field_in_natural_join(thd, table_list, name, length, ref,
|
||||||
/* TIMOUR_TODO: check this with Sanja */
|
|
||||||
check_grants_table || check_grants_view,
|
|
||||||
register_tree_change, actual_table);
|
register_tree_change, actual_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
/* Check if there are sufficient access rights to the found field. */
|
||||||
|
if (fld && check_privileges &&
|
||||||
|
check_column_grant_in_table_ref(thd, *actual_table, name, length))
|
||||||
|
fld= WRONG_GRANT;
|
||||||
|
#endif
|
||||||
|
|
||||||
DBUG_RETURN(fld);
|
DBUG_RETURN(fld);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3936,21 +3886,11 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
||||||
*/
|
*/
|
||||||
if (table_ref->table && !table_ref->view)
|
if (table_ref->table && !table_ref->view)
|
||||||
found= find_field_in_table(thd, table_ref->table, name, length,
|
found= find_field_in_table(thd, table_ref->table, name, length,
|
||||||
test(table_ref->table->
|
TRUE, &(item->cached_field_index));
|
||||||
grant.want_privilege) &&
|
|
||||||
check_privileges,
|
|
||||||
1, &(item->cached_field_index),
|
|
||||||
table_ref->security_ctx);
|
|
||||||
else
|
else
|
||||||
found= find_field_in_table_ref(thd, table_ref, name, item->name,
|
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
|
||||||
NULL, NULL, length, ref,
|
NULL, NULL, ref, check_privileges,
|
||||||
(table_ref->table &&
|
TRUE, &(item->cached_field_index),
|
||||||
test(table_ref->table->grant.
|
|
||||||
want_privilege) &&
|
|
||||||
check_privileges),
|
|
||||||
(test(table_ref->grant.want_privilege) &&
|
|
||||||
check_privileges),
|
|
||||||
1, &(item->cached_field_index),
|
|
||||||
register_tree_change,
|
register_tree_change,
|
||||||
&actual_table);
|
&actual_table);
|
||||||
if (found)
|
if (found)
|
||||||
|
@ -3990,17 +3930,9 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
||||||
for (; cur_table != last_table ;
|
for (; cur_table != last_table ;
|
||||||
cur_table= cur_table->next_name_resolution_table)
|
cur_table= cur_table->next_name_resolution_table)
|
||||||
{
|
{
|
||||||
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, item->name,
|
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
|
||||||
table_name, db,
|
item->name, db, table_name, ref,
|
||||||
length, ref,
|
check_privileges, allow_rowid,
|
||||||
(cur_table->table &&
|
|
||||||
test(cur_table->table->grant.
|
|
||||||
want_privilege) &&
|
|
||||||
check_privileges),
|
|
||||||
(test(cur_table->grant.
|
|
||||||
want_privilege)
|
|
||||||
&& check_privileges),
|
|
||||||
allow_rowid,
|
|
||||||
&(item->cached_field_index),
|
&(item->cached_field_index),
|
||||||
register_tree_change,
|
register_tree_change,
|
||||||
&actual_table);
|
&actual_table);
|
||||||
|
@ -4408,7 +4340,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||||
{
|
{
|
||||||
bool is_created_1;
|
bool is_created_1;
|
||||||
bool found= FALSE;
|
bool found= FALSE;
|
||||||
if (!(nj_col_1= it_1.get_or_create_column_ref(thd, &is_created_1)))
|
if (!(nj_col_1= it_1.get_or_create_column_ref(&is_created_1)))
|
||||||
goto err;
|
goto err;
|
||||||
field_name_1= nj_col_1->name();
|
field_name_1= nj_col_1->name();
|
||||||
|
|
||||||
|
@ -4429,7 +4361,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||||
bool is_created_2;
|
bool is_created_2;
|
||||||
Natural_join_column *cur_nj_col_2;
|
Natural_join_column *cur_nj_col_2;
|
||||||
const char *cur_field_name_2;
|
const char *cur_field_name_2;
|
||||||
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(thd, &is_created_2)))
|
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(&is_created_2)))
|
||||||
goto err;
|
goto err;
|
||||||
cur_field_name_2= cur_nj_col_2->name();
|
cur_field_name_2= cur_nj_col_2->name();
|
||||||
|
|
||||||
|
@ -4625,13 +4557,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
|
||||||
/* Append the columns of the first join operand. */
|
/* Append the columns of the first join operand. */
|
||||||
for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next())
|
for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next())
|
||||||
{
|
{
|
||||||
if (!(nj_col_1= it_1.get_or_create_column_ref(thd, &is_created)))
|
nj_col_1= it_1.get_natural_column_ref();
|
||||||
goto err;
|
|
||||||
/*
|
|
||||||
The following assert checks that mark_common_columns() was run and
|
|
||||||
we created the list table_ref_1->join_columns.
|
|
||||||
*/
|
|
||||||
DBUG_ASSERT(!is_created);
|
|
||||||
if (nj_col_1->is_common)
|
if (nj_col_1->is_common)
|
||||||
{
|
{
|
||||||
natural_using_join->join_columns->push_back(nj_col_1);
|
natural_using_join->join_columns->push_back(nj_col_1);
|
||||||
|
@ -4677,13 +4603,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
|
||||||
/* Append the non-equi-join columns of the second join operand. */
|
/* Append the non-equi-join columns of the second join operand. */
|
||||||
for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next())
|
for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next())
|
||||||
{
|
{
|
||||||
if (!(nj_col_2= it_2.get_or_create_column_ref(thd, &is_created)))
|
nj_col_2= it_2.get_natural_column_ref();
|
||||||
goto err;
|
|
||||||
/*
|
|
||||||
The following assert checks that mark_common_columns() was run and
|
|
||||||
we created the list table_ref_2->join_columns.
|
|
||||||
*/
|
|
||||||
DBUG_ASSERT(!is_created);
|
|
||||||
if (!nj_col_2->is_common)
|
if (!nj_col_2->is_common)
|
||||||
non_join_columns->push_back(nj_col_2);
|
non_join_columns->push_back(nj_col_2);
|
||||||
else
|
else
|
||||||
|
@ -5418,8 +5338,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
||||||
because it was already created and stored with the natural join.
|
because it was already created and stored with the natural join.
|
||||||
*/
|
*/
|
||||||
Natural_join_column *nj_col;
|
Natural_join_column *nj_col;
|
||||||
if (!(nj_col= field_iterator.get_or_create_column_ref(thd,
|
if (!(nj_col= field_iterator.get_or_create_column_ref(&is_created)))
|
||||||
&is_created)))
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
DBUG_ASSERT(nj_col->table_field && !is_created);
|
DBUG_ASSERT(nj_col->table_field && !is_created);
|
||||||
field_table= nj_col->table_ref->table;
|
field_table= nj_col->table_ref->table;
|
||||||
|
|
|
@ -1505,10 +1505,10 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
|
||||||
my_var *mv= gl++;
|
my_var *mv= gl++;
|
||||||
if (mv->local)
|
if (mv->local)
|
||||||
{
|
{
|
||||||
Item_splocal *var;
|
Item_splocal *var= new Item_splocal(mv->s, mv->offset, mv->type);
|
||||||
(void)local_vars.push_back(var= new Item_splocal(mv->s, mv->offset));
|
(void)local_vars.push_back(var);
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
var->owner= mv->owner;
|
var->m_sp= mv->sp;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1781,8 +1781,8 @@ bool select_dumpvar::send_data(List<Item> &items)
|
||||||
{
|
{
|
||||||
if ((yy=var_li++))
|
if ((yy=var_li++))
|
||||||
{
|
{
|
||||||
if (thd->spcont->set_item_eval(current_thd,
|
if (thd->spcont->set_variable(current_thd, yy->get_var_idx(),
|
||||||
yy->get_offset(), it.ref(), zz->type))
|
*it.ref()))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2111,7 +2111,7 @@ public:
|
||||||
Routine to which this Item_splocal belongs. Used for checking if correct
|
Routine to which this Item_splocal belongs. Used for checking if correct
|
||||||
runtime context is used for variable handling.
|
runtime context is used for variable handling.
|
||||||
*/
|
*/
|
||||||
sp_head *owner;
|
sp_head *sp;
|
||||||
#endif
|
#endif
|
||||||
bool local;
|
bool local;
|
||||||
uint offset;
|
uint offset;
|
||||||
|
|
|
@ -113,11 +113,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
||||||
{ // Part field list
|
{ // Part field list
|
||||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||||
Name_resolution_context *context= &select_lex->context;
|
Name_resolution_context *context= &select_lex->context;
|
||||||
TABLE_LIST *save_next_local;
|
Name_resolution_context_state ctx_state;
|
||||||
TABLE_LIST *save_table_list;
|
|
||||||
TABLE_LIST *save_first_name_resolution_table;
|
|
||||||
TABLE_LIST *save_next_name_resolution_table;
|
|
||||||
bool save_resolve_in_select_list;
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (fields.elements != values.elements)
|
if (fields.elements != values.elements)
|
||||||
|
@ -130,14 +126,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
||||||
select_lex->no_wrap_view_item= TRUE;
|
select_lex->no_wrap_view_item= TRUE;
|
||||||
|
|
||||||
/* Save the state of the current name resolution context. */
|
/* Save the state of the current name resolution context. */
|
||||||
save_table_list= context->table_list;
|
ctx_state.save_state(context, table_list);
|
||||||
save_first_name_resolution_table= context->first_name_resolution_table;
|
|
||||||
save_next_name_resolution_table= (context->first_name_resolution_table) ?
|
|
||||||
context->first_name_resolution_table->
|
|
||||||
next_name_resolution_table :
|
|
||||||
NULL;
|
|
||||||
save_resolve_in_select_list= context->resolve_in_select_list;
|
|
||||||
save_next_local= table_list->next_local;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Perform name resolution only in the first table - 'table_list',
|
Perform name resolution only in the first table - 'table_list',
|
||||||
|
@ -152,13 +141,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
||||||
res= setup_fields(thd, 0, fields, 2, 0, 0);
|
res= setup_fields(thd, 0, fields, 2, 0, 0);
|
||||||
|
|
||||||
/* Restore the current context. */
|
/* Restore the current context. */
|
||||||
table_list->next_local= save_next_local;
|
ctx_state.restore_state(context, table_list);
|
||||||
context->table_list= save_table_list;
|
|
||||||
context->first_name_resolution_table= save_first_name_resolution_table;
|
|
||||||
if (context->first_name_resolution_table)
|
|
||||||
context->first_name_resolution_table->
|
|
||||||
next_name_resolution_table= save_next_name_resolution_table;
|
|
||||||
context->resolve_in_select_list= save_resolve_in_select_list;
|
|
||||||
thd->lex->select_lex.no_wrap_view_item= FALSE;
|
thd->lex->select_lex.no_wrap_view_item= FALSE;
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -293,13 +276,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||||
ulonglong id;
|
ulonglong id;
|
||||||
COPY_INFO info;
|
COPY_INFO info;
|
||||||
TABLE *table= 0;
|
TABLE *table= 0;
|
||||||
TABLE_LIST *save_table_list;
|
|
||||||
TABLE_LIST *save_next_local;
|
|
||||||
TABLE_LIST *save_first_name_resolution_table;
|
|
||||||
TABLE_LIST *save_next_name_resolution_table;
|
|
||||||
List_iterator_fast<List_item> its(values_list);
|
List_iterator_fast<List_item> its(values_list);
|
||||||
List_item *values;
|
List_item *values;
|
||||||
Name_resolution_context *context;
|
Name_resolution_context *context;
|
||||||
|
Name_resolution_context_state ctx_state;
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
char *query= thd->query;
|
char *query= thd->query;
|
||||||
#endif
|
#endif
|
||||||
|
@ -380,13 +360,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||||
|
|
||||||
context= &thd->lex->select_lex.context;
|
context= &thd->lex->select_lex.context;
|
||||||
/* Save the state of the current name resolution context. */
|
/* Save the state of the current name resolution context. */
|
||||||
save_table_list= context->table_list;
|
ctx_state.save_state(context, table_list);
|
||||||
save_first_name_resolution_table= context->first_name_resolution_table;
|
|
||||||
save_next_name_resolution_table= (context->first_name_resolution_table) ?
|
|
||||||
context->first_name_resolution_table->
|
|
||||||
next_name_resolution_table :
|
|
||||||
NULL;
|
|
||||||
save_next_local= table_list->next_local;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Perform name resolution only in the first table - 'table_list',
|
Perform name resolution only in the first table - 'table_list',
|
||||||
|
@ -410,16 +384,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||||
its.rewind ();
|
its.rewind ();
|
||||||
|
|
||||||
/* Restore the current context. */
|
/* Restore the current context. */
|
||||||
table_list->next_local= save_next_local;
|
ctx_state.restore_state(context, table_list);
|
||||||
context->first_name_resolution_table= save_first_name_resolution_table;
|
|
||||||
if (context->first_name_resolution_table)
|
|
||||||
context->first_name_resolution_table->
|
|
||||||
next_name_resolution_table= save_next_name_resolution_table;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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= info.updated= 0;
|
info.records= info.deleted= info.copied= info.updated= 0;
|
||||||
info.ignore= ignore;
|
info.ignore= ignore;
|
||||||
info.handle_duplicates=duplic;
|
info.handle_duplicates=duplic;
|
||||||
|
@ -827,11 +796,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||||
{
|
{
|
||||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||||
Name_resolution_context *context= &select_lex->context;
|
Name_resolution_context *context= &select_lex->context;
|
||||||
TABLE_LIST *save_table_list;
|
Name_resolution_context_state ctx_state;
|
||||||
TABLE_LIST *save_next_local;
|
|
||||||
TABLE_LIST *save_first_name_resolution_table;
|
|
||||||
TABLE_LIST *save_next_name_resolution_table;
|
|
||||||
bool save_resolve_in_select_list;
|
|
||||||
bool insert_into_view= (table_list->view != 0);
|
bool insert_into_view= (table_list->view != 0);
|
||||||
bool res= 0;
|
bool res= 0;
|
||||||
DBUG_ENTER("mysql_prepare_insert");
|
DBUG_ENTER("mysql_prepare_insert");
|
||||||
|
@ -871,15 +836,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/* Save the state of the current name resolution context. */
|
/* Save the state of the current name resolution context. */
|
||||||
save_table_list= context->table_list;
|
ctx_state.save_state(context, table_list);
|
||||||
/* Here first_name_resolution_table points to the first select table. */
|
|
||||||
save_first_name_resolution_table= context->first_name_resolution_table;
|
|
||||||
save_next_name_resolution_table= (context->first_name_resolution_table) ?
|
|
||||||
context->first_name_resolution_table->
|
|
||||||
next_name_resolution_table :
|
|
||||||
NULL;
|
|
||||||
save_resolve_in_select_list= context->resolve_in_select_list;
|
|
||||||
save_next_local= table_list->next_local;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Perform name resolution only in the first table - 'table_list',
|
Perform name resolution only in the first table - 'table_list',
|
||||||
|
@ -904,23 +861,17 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||||
*/
|
*/
|
||||||
if (select_lex->group_list.elements == 0)
|
if (select_lex->group_list.elements == 0)
|
||||||
{
|
{
|
||||||
context->table_list->next_local= save_next_local;
|
context->table_list->next_local= ctx_state.save_next_local;
|
||||||
/* first_name_resolution_table was set by resolve_in_table_list_only() */
|
/* first_name_resolution_table was set by resolve_in_table_list_only() */
|
||||||
context->first_name_resolution_table->
|
context->first_name_resolution_table->
|
||||||
next_name_resolution_table= save_next_local;
|
next_name_resolution_table= ctx_state.save_next_local;
|
||||||
}
|
}
|
||||||
if (!res)
|
if (!res)
|
||||||
res= setup_fields(thd, 0, update_values, 1, 0, 0);
|
res= setup_fields(thd, 0, update_values, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the current context. */
|
/* Restore the current context. */
|
||||||
table_list->next_local= save_next_local;
|
ctx_state.restore_state(context, table_list);
|
||||||
context->table_list= save_table_list;
|
|
||||||
context->first_name_resolution_table= save_first_name_resolution_table;
|
|
||||||
if (context->first_name_resolution_table)
|
|
||||||
context->first_name_resolution_table->
|
|
||||||
next_name_resolution_table= save_next_name_resolution_table;
|
|
||||||
context->resolve_in_select_list= save_resolve_in_select_list;
|
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
|
@ -2187,17 +2138,10 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||||
{
|
{
|
||||||
/* Save the state of the current name resolution context. */
|
/* Save the state of the current name resolution context. */
|
||||||
Name_resolution_context *context= &lex->select_lex.context;
|
Name_resolution_context *context= &lex->select_lex.context;
|
||||||
TABLE_LIST *save_table_list;
|
Name_resolution_context_state ctx_state;
|
||||||
TABLE_LIST *save_next_local;
|
|
||||||
TABLE_LIST *save_first_name_resolution_table;
|
/* Save the state of the current name resolution context. */
|
||||||
TABLE_LIST *save_next_name_resolution_table;
|
ctx_state.save_state(context, table_list);
|
||||||
save_table_list= context->table_list;
|
|
||||||
save_first_name_resolution_table= context->first_name_resolution_table;
|
|
||||||
save_next_name_resolution_table= (context->first_name_resolution_table) ?
|
|
||||||
context->first_name_resolution_table->
|
|
||||||
next_name_resolution_table :
|
|
||||||
NULL;
|
|
||||||
save_next_local= table_list->next_local;
|
|
||||||
|
|
||||||
/* Perform name resolution only in the first table - 'table_list'. */
|
/* Perform name resolution only in the first table - 'table_list'. */
|
||||||
table_list->next_local= 0;
|
table_list->next_local= 0;
|
||||||
|
@ -2213,20 +2157,15 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||||
*/
|
*/
|
||||||
if (lex->select_lex.group_list.elements == 0)
|
if (lex->select_lex.group_list.elements == 0)
|
||||||
{
|
{
|
||||||
context->table_list->next_local= save_next_local;
|
context->table_list->next_local= ctx_state.save_next_local;
|
||||||
/* first_name_resolution_table was set by resolve_in_table_list_only() */
|
/* first_name_resolution_table was set by resolve_in_table_list_only() */
|
||||||
context->first_name_resolution_table->
|
context->first_name_resolution_table->
|
||||||
next_name_resolution_table= save_next_local;
|
next_name_resolution_table= ctx_state.save_next_local;
|
||||||
}
|
}
|
||||||
res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0);
|
res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0);
|
||||||
|
|
||||||
/* Restore the current context. */
|
/* Restore the current context. */
|
||||||
table_list->next_local= save_next_local;
|
ctx_state.restore_state(context, table_list);
|
||||||
context->first_name_resolution_table= save_first_name_resolution_table;
|
|
||||||
if (context->first_name_resolution_table)
|
|
||||||
context->first_name_resolution_table->
|
|
||||||
next_name_resolution_table= save_next_name_resolution_table;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lex->current_select= lex_current_select_save;
|
lex->current_select= lex_current_select_save;
|
||||||
|
|
|
@ -1130,6 +1130,11 @@ void st_select_lex::init_query()
|
||||||
/*
|
/*
|
||||||
Add the name resolution context of the current (sub)query to the
|
Add the name resolution context of the current (sub)query to the
|
||||||
stack of contexts for the whole query.
|
stack of contexts for the whole query.
|
||||||
|
TODO:
|
||||||
|
push_context may return an error if there is no memory for a new
|
||||||
|
element in the stack, however this method has no return value,
|
||||||
|
thus push_context should be moved to a place where query
|
||||||
|
initialization is checked for failure.
|
||||||
*/
|
*/
|
||||||
parent_lex->push_context(&context);
|
parent_lex->push_context(&context);
|
||||||
cond_count= with_wild= 0;
|
cond_count= with_wild= 0;
|
||||||
|
|
|
@ -1024,9 +1024,9 @@ typedef struct st_lex
|
||||||
}
|
}
|
||||||
void cleanup_after_one_table_open();
|
void cleanup_after_one_table_open();
|
||||||
|
|
||||||
void push_context(Name_resolution_context *context)
|
bool push_context(Name_resolution_context *context)
|
||||||
{
|
{
|
||||||
context_stack.push_front(context);
|
return context_stack.push_front(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_context()
|
void pop_context()
|
||||||
|
|
|
@ -266,10 +266,21 @@ protected:
|
||||||
ls.elements= elm;
|
ls.elements= elm;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
base_list_iterator(base_list &list_par)
|
base_list_iterator()
|
||||||
:list(&list_par), el(&list_par.first), prev(0), current(0)
|
:list(0), el(0), prev(0), current(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
base_list_iterator(base_list &list_par)
|
||||||
|
{ init(list_par); }
|
||||||
|
|
||||||
|
inline void init(base_list &list_par)
|
||||||
|
{
|
||||||
|
list= &list_par;
|
||||||
|
el= &list_par.first;
|
||||||
|
prev= 0;
|
||||||
|
current= 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline void *next(void)
|
inline void *next(void)
|
||||||
{
|
{
|
||||||
prev=el;
|
prev=el;
|
||||||
|
@ -364,6 +375,8 @@ template <class T> class List_iterator :public base_list_iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
List_iterator(List<T> &a) : base_list_iterator(a) {}
|
List_iterator(List<T> &a) : base_list_iterator(a) {}
|
||||||
|
List_iterator() : base_list_iterator() {}
|
||||||
|
inline void init(List<T> &a) { base_list_iterator::init(a); }
|
||||||
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
|
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
|
||||||
inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
|
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 T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
|
||||||
|
@ -385,6 +398,8 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
|
inline List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
|
||||||
|
inline List_iterator_fast() : base_list_iterator() {}
|
||||||
|
inline void init(List<T> &a) { base_list_iterator::init(a); }
|
||||||
inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
|
inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
|
||||||
inline void rewind(void) { base_list_iterator::rewind(); }
|
inline void rewind(void) { base_list_iterator::rewind(); }
|
||||||
void sublist(List<T> &list_arg, uint el_arg)
|
void sublist(List<T> &list_arg, uint el_arg)
|
||||||
|
|
372
sql/sql_parse.cc
372
sql/sql_parse.cc
|
@ -2614,7 +2614,8 @@ mysql_execute_command(THD *thd)
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||||
res = mysql_backup_table(thd, first_table);
|
res = mysql_backup_table(thd, first_table);
|
||||||
|
select_lex->table_list.first= (byte*) first_table;
|
||||||
|
lex->query_tables=all_tables;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_RESTORE_TABLE:
|
case SQLCOM_RESTORE_TABLE:
|
||||||
|
@ -2626,6 +2627,8 @@ mysql_execute_command(THD *thd)
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||||
res = mysql_restore_table(thd, first_table);
|
res = mysql_restore_table(thd, first_table);
|
||||||
|
select_lex->table_list.first= (byte*) first_table;
|
||||||
|
lex->query_tables=all_tables;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_ASSIGN_TO_KEYCACHE:
|
case SQLCOM_ASSIGN_TO_KEYCACHE:
|
||||||
|
@ -3119,6 +3122,8 @@ end_with_restore_list:
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
select_lex->table_list.first= (byte*) first_table;
|
||||||
|
lex->query_tables=all_tables;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_CHECK:
|
case SQLCOM_CHECK:
|
||||||
|
@ -3129,6 +3134,8 @@ end_with_restore_list:
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||||
res = mysql_check_table(thd, first_table, &lex->check_opt);
|
res = mysql_check_table(thd, first_table, &lex->check_opt);
|
||||||
|
select_lex->table_list.first= (byte*) first_table;
|
||||||
|
lex->query_tables=all_tables;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_ANALYZE:
|
case SQLCOM_ANALYZE:
|
||||||
|
@ -3149,6 +3156,8 @@ end_with_restore_list:
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
select_lex->table_list.first= (byte*) first_table;
|
||||||
|
lex->query_tables=all_tables;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3172,6 +3181,8 @@ end_with_restore_list:
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
select_lex->table_list.first= (byte*) first_table;
|
||||||
|
lex->query_tables=all_tables;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_UPDATE:
|
case SQLCOM_UPDATE:
|
||||||
|
@ -4122,14 +4133,6 @@ end_with_restore_list:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
|
|
||||||
!(lex->sphead->m_flags & sp_head::HAS_RETURN))
|
|
||||||
{
|
|
||||||
my_error(ER_SP_NORETURN, MYF(0), name);
|
|
||||||
delete lex->sphead;
|
|
||||||
lex->sphead= 0;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We need to copy name and db in order to use them for
|
We need to copy name and db in order to use them for
|
||||||
|
@ -5765,9 +5768,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
||||||
buf, "TIMESTAMP");
|
buf, "TIMESTAMP");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(new_field= new_create_field(thd, field_name, type, length, decimals,
|
if (!(new_field= new create_field()) ||
|
||||||
type_modifier, default_value, on_update_value,
|
new_field->init(thd, field_name, type, length, decimals, type_modifier,
|
||||||
comment, change, interval_list, cs, uint_geom_type)))
|
default_value, on_update_value, comment, change,
|
||||||
|
interval_list, cs, uint_geom_type))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
lex->create_list.push_back(new_field);
|
lex->create_list.push_back(new_field);
|
||||||
|
@ -5775,327 +5779,6 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
** Create field definition for create
|
|
||||||
** Return 0 on failure, otherwise return create_field instance
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
create_field *
|
|
||||||
new_create_field(THD *thd, char *field_name, enum_field_types type,
|
|
||||||
char *length, char *decimals,
|
|
||||||
uint type_modifier,
|
|
||||||
Item *default_value, Item *on_update_value,
|
|
||||||
LEX_STRING *comment,
|
|
||||||
char *change, List<String> *interval_list, CHARSET_INFO *cs,
|
|
||||||
uint uint_geom_type)
|
|
||||||
{
|
|
||||||
register create_field *new_field;
|
|
||||||
uint sign_len, allowed_type_modifier=0;
|
|
||||||
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
|
|
||||||
DBUG_ENTER("new_create_field");
|
|
||||||
|
|
||||||
if (!(new_field=new create_field()))
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
new_field->field=0;
|
|
||||||
new_field->field_name=field_name;
|
|
||||||
new_field->def= default_value;
|
|
||||||
new_field->flags= type_modifier;
|
|
||||||
new_field->unireg_check= (type_modifier & AUTO_INCREMENT_FLAG ?
|
|
||||||
Field::NEXT_NUMBER : Field::NONE);
|
|
||||||
new_field->decimals= decimals ? (uint)atoi(decimals) : 0;
|
|
||||||
if (new_field->decimals >= NOT_FIXED_DEC)
|
|
||||||
{
|
|
||||||
my_error(ER_TOO_BIG_SCALE, MYF(0), new_field->decimals, field_name,
|
|
||||||
NOT_FIXED_DEC-1);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
new_field->sql_type=type;
|
|
||||||
new_field->length=0;
|
|
||||||
new_field->change=change;
|
|
||||||
new_field->interval=0;
|
|
||||||
new_field->pack_length= new_field->key_length= 0;
|
|
||||||
new_field->charset=cs;
|
|
||||||
new_field->geom_type= (Field::geometry_type) uint_geom_type;
|
|
||||||
|
|
||||||
new_field->comment=*comment;
|
|
||||||
/*
|
|
||||||
Set flag if this field doesn't have a default value
|
|
||||||
*/
|
|
||||||
if (!default_value && !(type_modifier & AUTO_INCREMENT_FLAG) &&
|
|
||||||
(type_modifier & NOT_NULL_FLAG) && type != FIELD_TYPE_TIMESTAMP)
|
|
||||||
new_field->flags|= NO_DEFAULT_VALUE_FLAG;
|
|
||||||
|
|
||||||
if (length && !(new_field->length= (uint) atoi(length)))
|
|
||||||
length=0; /* purecov: inspected */
|
|
||||||
sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case FIELD_TYPE_TINY:
|
|
||||||
if (!length) new_field->length=MAX_TINYINT_WIDTH+sign_len;
|
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_SHORT:
|
|
||||||
if (!length) new_field->length=MAX_SMALLINT_WIDTH+sign_len;
|
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_INT24:
|
|
||||||
if (!length) new_field->length=MAX_MEDIUMINT_WIDTH+sign_len;
|
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_LONG:
|
|
||||||
if (!length) new_field->length=MAX_INT_WIDTH+sign_len;
|
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_LONGLONG:
|
|
||||||
if (!length) new_field->length=MAX_BIGINT_WIDTH;
|
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_NULL:
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_NEWDECIMAL:
|
|
||||||
if (!length && !new_field->decimals)
|
|
||||||
new_field->length= 10;
|
|
||||||
if (new_field->length > DECIMAL_MAX_PRECISION)
|
|
||||||
{
|
|
||||||
my_error(ER_TOO_BIG_PRECISION, MYF(0), new_field->length, field_name,
|
|
||||||
DECIMAL_MAX_PRECISION);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
if (new_field->length < new_field->decimals)
|
|
||||||
{
|
|
||||||
my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
new_field->length=
|
|
||||||
my_decimal_precision_to_length(new_field->length, new_field->decimals,
|
|
||||||
type_modifier & UNSIGNED_FLAG);
|
|
||||||
new_field->pack_length=
|
|
||||||
my_decimal_get_binary_size(new_field->length, new_field->decimals);
|
|
||||||
break;
|
|
||||||
case MYSQL_TYPE_VARCHAR:
|
|
||||||
/*
|
|
||||||
Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
|
|
||||||
if they don't have a default value
|
|
||||||
*/
|
|
||||||
max_field_charlength= MAX_FIELD_VARCHARLENGTH;
|
|
||||||
break;
|
|
||||||
case MYSQL_TYPE_STRING:
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_BLOB:
|
|
||||||
case FIELD_TYPE_TINY_BLOB:
|
|
||||||
case FIELD_TYPE_LONG_BLOB:
|
|
||||||
case FIELD_TYPE_MEDIUM_BLOB:
|
|
||||||
case FIELD_TYPE_GEOMETRY:
|
|
||||||
if (default_value) // Allow empty as default value
|
|
||||||
{
|
|
||||||
String str,*res;
|
|
||||||
res=default_value->val_str(&str);
|
|
||||||
if (res->length())
|
|
||||||
{
|
|
||||||
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
|
|
||||||
field_name); /* purecov: inspected */
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
new_field->def=0;
|
|
||||||
}
|
|
||||||
new_field->flags|=BLOB_FLAG;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_YEAR:
|
|
||||||
if (!length || new_field->length != 2)
|
|
||||||
new_field->length=4; // Default length
|
|
||||||
new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_FLOAT:
|
|
||||||
/* change FLOAT(precision) to FLOAT or DOUBLE */
|
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
|
||||||
if (length && !decimals)
|
|
||||||
{
|
|
||||||
uint tmp_length=new_field->length;
|
|
||||||
if (tmp_length > PRECISION_FOR_DOUBLE)
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
else if (tmp_length > PRECISION_FOR_FLOAT)
|
|
||||||
{
|
|
||||||
new_field->sql_type=FIELD_TYPE_DOUBLE;
|
|
||||||
new_field->length=DBL_DIG+7; // -[digits].E+###
|
|
||||||
}
|
|
||||||
else
|
|
||||||
new_field->length=FLT_DIG+6; // -[digits].E+##
|
|
||||||
new_field->decimals= NOT_FIXED_DEC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!length && !decimals)
|
|
||||||
{
|
|
||||||
new_field->length = FLT_DIG+6;
|
|
||||||
new_field->decimals= NOT_FIXED_DEC;
|
|
||||||
}
|
|
||||||
if (new_field->length < new_field->decimals &&
|
|
||||||
new_field->decimals != NOT_FIXED_DEC)
|
|
||||||
{
|
|
||||||
my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_DOUBLE:
|
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
|
||||||
if (!length && !decimals)
|
|
||||||
{
|
|
||||||
new_field->length = DBL_DIG+7;
|
|
||||||
new_field->decimals=NOT_FIXED_DEC;
|
|
||||||
}
|
|
||||||
if (new_field->length < new_field->decimals &&
|
|
||||||
new_field->decimals != NOT_FIXED_DEC)
|
|
||||||
{
|
|
||||||
my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_TIMESTAMP:
|
|
||||||
if (!length)
|
|
||||||
new_field->length= 14; // Full date YYYYMMDDHHMMSS
|
|
||||||
else if (new_field->length != 19)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
We support only even TIMESTAMP lengths less or equal than 14
|
|
||||||
and 19 as length of 4.1 compatible representation.
|
|
||||||
*/
|
|
||||||
new_field->length=((new_field->length+1)/2)*2; /* purecov: inspected */
|
|
||||||
new_field->length= min(new_field->length,14); /* purecov: inspected */
|
|
||||||
}
|
|
||||||
new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
|
|
||||||
if (default_value)
|
|
||||||
{
|
|
||||||
/* Grammar allows only NOW() value for ON UPDATE clause */
|
|
||||||
if (default_value->type() == Item::FUNC_ITEM &&
|
|
||||||
((Item_func*)default_value)->functype() == Item_func::NOW_FUNC)
|
|
||||||
{
|
|
||||||
new_field->unireg_check= (on_update_value?Field::TIMESTAMP_DNUN_FIELD:
|
|
||||||
Field::TIMESTAMP_DN_FIELD);
|
|
||||||
/*
|
|
||||||
We don't need default value any longer moreover it is dangerous.
|
|
||||||
Everything handled by unireg_check further.
|
|
||||||
*/
|
|
||||||
new_field->def= 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
new_field->unireg_check= (on_update_value?Field::TIMESTAMP_UN_FIELD:
|
|
||||||
Field::NONE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
|
|
||||||
or ON UPDATE values then for the sake of compatiblity we should treat
|
|
||||||
this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
|
|
||||||
have another TIMESTAMP column with auto-set option before this one)
|
|
||||||
or DEFAULT 0 (in other cases).
|
|
||||||
So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
|
|
||||||
replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
|
|
||||||
information about all TIMESTAMP fields in table will be availiable.
|
|
||||||
|
|
||||||
If we have TIMESTAMP NULL column without explicit DEFAULT value
|
|
||||||
we treat it as having DEFAULT NULL attribute.
|
|
||||||
*/
|
|
||||||
new_field->unireg_check= (on_update_value ?
|
|
||||||
Field::TIMESTAMP_UN_FIELD :
|
|
||||||
(new_field->flags & NOT_NULL_FLAG ?
|
|
||||||
Field::TIMESTAMP_OLD_FIELD:
|
|
||||||
Field::NONE));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_DATE: // Old date type
|
|
||||||
if (protocol_version != PROTOCOL_VERSION-1)
|
|
||||||
new_field->sql_type=FIELD_TYPE_NEWDATE;
|
|
||||||
/* fall trough */
|
|
||||||
case FIELD_TYPE_NEWDATE:
|
|
||||||
new_field->length=10;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_TIME:
|
|
||||||
new_field->length=10;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_DATETIME:
|
|
||||||
new_field->length=19;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_SET:
|
|
||||||
{
|
|
||||||
if (interval_list->elements > sizeof(longlong)*8)
|
|
||||||
{
|
|
||||||
my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
new_field->pack_length= get_set_pack_length(interval_list->elements);
|
|
||||||
|
|
||||||
List_iterator<String> it(*interval_list);
|
|
||||||
String *tmp;
|
|
||||||
while ((tmp= it++))
|
|
||||||
new_field->interval_list.push_back(tmp);
|
|
||||||
/*
|
|
||||||
Set fake length to 1 to pass the below conditions.
|
|
||||||
Real length will be set in mysql_prepare_table()
|
|
||||||
when we know the character set of the column
|
|
||||||
*/
|
|
||||||
new_field->length= 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FIELD_TYPE_ENUM:
|
|
||||||
{
|
|
||||||
// Should be safe
|
|
||||||
new_field->pack_length= get_enum_pack_length(interval_list->elements);
|
|
||||||
|
|
||||||
List_iterator<String> it(*interval_list);
|
|
||||||
String *tmp;
|
|
||||||
while ((tmp= it++))
|
|
||||||
new_field->interval_list.push_back(tmp);
|
|
||||||
new_field->length= 1; // See comment for FIELD_TYPE_SET above.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
|
||||||
DBUG_ASSERT(0); // Impossible
|
|
||||||
break;
|
|
||||||
case MYSQL_TYPE_BIT:
|
|
||||||
{
|
|
||||||
if (!length)
|
|
||||||
new_field->length= 1;
|
|
||||||
if (new_field->length > MAX_BIT_FIELD_LENGTH)
|
|
||||||
{
|
|
||||||
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name,
|
|
||||||
MAX_BIT_FIELD_LENGTH);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
new_field->pack_length= (new_field->length + 7) / 8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FIELD_TYPE_DECIMAL:
|
|
||||||
DBUG_ASSERT(0); /* Was obsolete */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(new_field->flags & BLOB_FLAG) &&
|
|
||||||
((new_field->length > max_field_charlength && type != FIELD_TYPE_SET &&
|
|
||||||
type != FIELD_TYPE_ENUM &&
|
|
||||||
(type != MYSQL_TYPE_VARCHAR || default_value)) ||
|
|
||||||
(!new_field->length &&
|
|
||||||
type != MYSQL_TYPE_STRING &&
|
|
||||||
type != MYSQL_TYPE_VARCHAR && type != FIELD_TYPE_GEOMETRY)))
|
|
||||||
{
|
|
||||||
my_error((type == MYSQL_TYPE_VAR_STRING || type == MYSQL_TYPE_VARCHAR ||
|
|
||||||
type == MYSQL_TYPE_STRING) ? ER_TOO_BIG_FIELDLENGTH :
|
|
||||||
ER_TOO_BIG_DISPLAYWIDTH,
|
|
||||||
MYF(0),
|
|
||||||
field_name, max_field_charlength); /* purecov: inspected */
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
type_modifier&= AUTO_INCREMENT_FLAG;
|
|
||||||
if ((~allowed_type_modifier) & type_modifier)
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
DBUG_RETURN(new_field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Store position for column in ALTER TABLE .. ADD column */
|
/* Store position for column in ALTER TABLE .. ADD column */
|
||||||
|
|
||||||
|
@ -6593,36 +6276,39 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a new name resolution context for a JOIN ... ON clause.
|
Push a new name resolution context for a JOIN ... ON clause to the
|
||||||
|
context stack of a query block.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
make_join_on_context()
|
push_new_name_resolution_context()
|
||||||
thd pointer to current thread
|
thd pointer to current thread
|
||||||
left_op left operand of the JOIN
|
left_op left operand of the JOIN
|
||||||
right_op rigth operand of the JOIN
|
right_op rigth operand of the JOIN
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Create a new name resolution context for a JOIN ... ON clause,
|
Create a new name resolution context for a JOIN ... ON clause,
|
||||||
and set the first and last leaves of the list of table references
|
set the first and last leaves of the list of table references
|
||||||
to be used for name resolution.
|
to be used for name resolution, and push the newly created
|
||||||
|
context to the stack of contexts of the query.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
A new context if all is OK
|
FALSE if all is OK
|
||||||
NULL - if a memory allocation error occured
|
TRUE if a memory allocation error occured
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Name_resolution_context *
|
bool
|
||||||
make_join_on_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op)
|
push_new_name_resolution_context(THD *thd,
|
||||||
|
TABLE_LIST *left_op, TABLE_LIST *right_op)
|
||||||
{
|
{
|
||||||
Name_resolution_context *on_context;
|
Name_resolution_context *on_context;
|
||||||
if (!(on_context= new (thd->mem_root) Name_resolution_context))
|
if (!(on_context= new (thd->mem_root) Name_resolution_context))
|
||||||
return NULL;
|
return TRUE;
|
||||||
on_context->init();
|
on_context->init();
|
||||||
on_context->first_name_resolution_table=
|
on_context->first_name_resolution_table=
|
||||||
left_op->first_leaf_for_name_resolution();
|
left_op->first_leaf_for_name_resolution();
|
||||||
on_context->last_name_resolution_table=
|
on_context->last_name_resolution_table=
|
||||||
right_op->last_leaf_for_name_resolution();
|
right_op->last_leaf_for_name_resolution();
|
||||||
return on_context;
|
return thd->lex->push_context(on_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8951,6 +8951,7 @@ err:
|
||||||
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
|
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
|
||||||
{
|
{
|
||||||
uint field_count= field_list.elements;
|
uint field_count= field_list.elements;
|
||||||
|
uint blob_count= 0;
|
||||||
Field **field;
|
Field **field;
|
||||||
create_field *cdef; /* column definition */
|
create_field *cdef; /* column definition */
|
||||||
uint record_length= 0;
|
uint record_length= 0;
|
||||||
|
@ -8967,6 +8968,12 @@ TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
|
||||||
table->s= share= (TABLE_SHARE*) (table+1);
|
table->s= share= (TABLE_SHARE*) (table+1);
|
||||||
share->fields= field_count;
|
share->fields= field_count;
|
||||||
|
|
||||||
|
if (!(share->blob_field= (uint*)thd->alloc((field_list.elements + 1) *
|
||||||
|
sizeof(uint))))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
share->blob_ptr_size= mi_portable_sizeof_char_ptr;
|
||||||
|
|
||||||
/* Create all fields and calculate the total length of record */
|
/* Create all fields and calculate the total length of record */
|
||||||
List_iterator_fast<create_field> it(field_list);
|
List_iterator_fast<create_field> it(field_list);
|
||||||
while ((cdef= it++))
|
while ((cdef= it++))
|
||||||
|
@ -8983,9 +8990,15 @@ TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
|
||||||
record_length+= (*field)->pack_length();
|
record_length+= (*field)->pack_length();
|
||||||
if (! ((*field)->flags & NOT_NULL_FLAG))
|
if (! ((*field)->flags & NOT_NULL_FLAG))
|
||||||
null_count++;
|
null_count++;
|
||||||
|
|
||||||
|
if ((*field)->flags & BLOB_FLAG)
|
||||||
|
share->blob_field[blob_count++]= (uint) (field - table->field);
|
||||||
|
|
||||||
field++;
|
field++;
|
||||||
}
|
}
|
||||||
*field= NULL; /* mark the end of the list */
|
*field= NULL; /* mark the end of the list */
|
||||||
|
share->blob_field[blob_count]= 0; /* mark the end of the list */
|
||||||
|
share->blob_fields= blob_count;
|
||||||
|
|
||||||
null_pack_length= (null_count + 7)/8;
|
null_pack_length= (null_count + 7)/8;
|
||||||
share->reclength= record_length + null_pack_length;
|
share->reclength= record_length + null_pack_length;
|
||||||
|
|
|
@ -407,7 +407,6 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||||
ORDER *group, bool distinct, bool save_sum_fields,
|
ORDER *group, bool distinct, bool save_sum_fields,
|
||||||
ulonglong select_options, ha_rows rows_limit,
|
ulonglong select_options, ha_rows rows_limit,
|
||||||
char* alias);
|
char* alias);
|
||||||
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list);
|
|
||||||
void free_tmp_table(THD *thd, TABLE *entry);
|
void free_tmp_table(THD *thd, TABLE *entry);
|
||||||
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
|
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
|
||||||
bool reset_with_sum_func);
|
bool reset_with_sum_func);
|
||||||
|
|
|
@ -2412,18 +2412,14 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||||
*/
|
*/
|
||||||
lex->query_tables= table;
|
lex->query_tables= table;
|
||||||
lex->query_tables_last= &table->next_global;
|
lex->query_tables_last= &table->next_global;
|
||||||
lex->query_tables_own_last= 0;;
|
lex->query_tables_own_last= 0;
|
||||||
thd->no_warnings_for_error= no_warnings_for_error;
|
thd->no_warnings_for_error= no_warnings_for_error;
|
||||||
|
if (view_operator_func == NULL)
|
||||||
|
table->required_type=FRMTYPE_TABLE;
|
||||||
open_and_lock_tables(thd, table);
|
open_and_lock_tables(thd, table);
|
||||||
thd->no_warnings_for_error= 0;
|
thd->no_warnings_for_error= 0;
|
||||||
table->next_global= save_next_global;
|
table->next_global= save_next_global;
|
||||||
table->next_local= save_next_local;
|
table->next_local= save_next_local;
|
||||||
/* if view are unsupported */
|
|
||||||
if (table->view && view_operator_func == NULL)
|
|
||||||
{
|
|
||||||
result_code= HA_ADMIN_NOT_BASE_TABLE;
|
|
||||||
goto send_result;
|
|
||||||
}
|
|
||||||
thd->open_options&= ~extra_open_options;
|
thd->open_options&= ~extra_open_options;
|
||||||
|
|
||||||
if (prepare_func)
|
if (prepare_func)
|
||||||
|
|
|
@ -1123,7 +1123,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
|
||||||
trg_action_time_type time_type,
|
trg_action_time_type time_type,
|
||||||
bool old_row_is_record1)
|
bool old_row_is_record1)
|
||||||
{
|
{
|
||||||
int res= 0;
|
bool err_status= FALSE;
|
||||||
sp_head *sp_trigger= bodies[event][time_type];
|
sp_head *sp_trigger= bodies[event][time_type];
|
||||||
|
|
||||||
if (sp_trigger)
|
if (sp_trigger)
|
||||||
|
@ -1183,7 +1183,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
|
||||||
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
|
||||||
thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER);
|
thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER);
|
||||||
res= sp_trigger->execute_function(thd, 0, 0, 0);
|
err_status= sp_trigger->execute_function(thd, 0, 0, 0);
|
||||||
thd->restore_sub_statement_state(&statement_state);
|
thd->restore_sub_statement_state(&statement_state);
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
@ -1191,7 +1191,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
|
||||||
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return err_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ public:
|
||||||
void set_table(TABLE *new_table);
|
void set_table(TABLE *new_table);
|
||||||
|
|
||||||
friend class Item_trigger_field;
|
friend class Item_trigger_field;
|
||||||
friend void sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
friend int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers);
|
Table_triggers_list *triggers);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
258
sql/sql_yacc.yy
258
sql/sql_yacc.yy
|
@ -1377,41 +1377,11 @@ create_function_tail:
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
sp_head *sp= lex->sphead;
|
||||||
LEX_STRING cmt = { 0, 0 };
|
|
||||||
create_field *new_field;
|
|
||||||
uint unused1= 0;
|
|
||||||
int unused2= 0;
|
|
||||||
|
|
||||||
if (!(new_field= new_create_field(YYTHD, (char*) "",
|
if (sp->fill_field_definition(YYTHD, lex,
|
||||||
(enum enum_field_types)$8,
|
(enum enum_field_types) $8,
|
||||||
lex->length, lex->dec, lex->type,
|
&sp->m_return_field_def))
|
||||||
(Item *)0, (Item *) 0, &cmt, 0,
|
YYABORT;
|
||||||
&lex->interval_list,
|
|
||||||
(lex->charset ? lex->charset :
|
|
||||||
default_charset_info),
|
|
||||||
lex->uint_geom_type)))
|
|
||||||
YYABORT;
|
|
||||||
|
|
||||||
sp->m_returns_cs= new_field->charset;
|
|
||||||
|
|
||||||
if (new_field->interval_list.elements)
|
|
||||||
{
|
|
||||||
new_field->interval=
|
|
||||||
sp->create_typelib(&new_field->interval_list);
|
|
||||||
}
|
|
||||||
sp_prepare_create_field(YYTHD, new_field);
|
|
||||||
|
|
||||||
if (prepare_create_field(new_field, &unused1, &unused2, &unused2,
|
|
||||||
HA_CAN_GEOMETRY))
|
|
||||||
YYABORT;
|
|
||||||
|
|
||||||
sp->m_returns= new_field->sql_type;
|
|
||||||
sp->m_returns_cs= new_field->charset;
|
|
||||||
sp->m_returns_len= new_field->length;
|
|
||||||
sp->m_returns_pack= new_field->pack_flag;
|
|
||||||
sp->m_returns_typelib= new_field->interval;
|
|
||||||
sp->m_geom_returns= new_field->geom_type;
|
|
||||||
new_field->interval= NULL;
|
|
||||||
|
|
||||||
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
|
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
|
||||||
}
|
}
|
||||||
|
@ -1434,6 +1404,11 @@ create_function_tail:
|
||||||
YYABORT;
|
YYABORT;
|
||||||
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
||||||
sp->init_strings(YYTHD, lex, lex->spname);
|
sp->init_strings(YYTHD, lex, lex->spname);
|
||||||
|
if (!(sp->m_flags & sp_head::HAS_RETURN))
|
||||||
|
{
|
||||||
|
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
/* Restore flag if it was cleared above */
|
/* Restore flag if it was cleared above */
|
||||||
if (sp->m_old_cmq)
|
if (sp->m_old_cmq)
|
||||||
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
||||||
|
@ -1528,8 +1503,28 @@ sp_fdparams:
|
||||||
| sp_fdparam
|
| sp_fdparam
|
||||||
;
|
;
|
||||||
|
|
||||||
|
sp_init_param:
|
||||||
|
/* Empty */
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
|
||||||
|
lex->length= 0;
|
||||||
|
lex->dec= 0;
|
||||||
|
lex->type= 0;
|
||||||
|
|
||||||
|
lex->default_value= 0;
|
||||||
|
lex->on_update_value= 0;
|
||||||
|
|
||||||
|
lex->comment= null_lex_str;
|
||||||
|
lex->charset= NULL;
|
||||||
|
|
||||||
|
lex->interval_list.empty();
|
||||||
|
lex->uint_geom_type= 0;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
sp_fdparam:
|
sp_fdparam:
|
||||||
ident type
|
ident sp_init_param type
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_pcontext *spc= lex->spcont;
|
sp_pcontext *spc= lex->spcont;
|
||||||
|
@ -1539,7 +1534,17 @@ sp_fdparam:
|
||||||
my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
|
my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in);
|
sp_pvar_t *pvar= spc->push_pvar(&$1, (enum enum_field_types)$3,
|
||||||
|
sp_param_in);
|
||||||
|
|
||||||
|
if (lex->sphead->fill_field_definition(YYTHD, lex,
|
||||||
|
(enum enum_field_types) $3,
|
||||||
|
&pvar->field_def))
|
||||||
|
{
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
pvar->field_def.field_name= pvar->name.str;
|
||||||
|
pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1555,18 +1560,27 @@ sp_pdparams:
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_pdparam:
|
sp_pdparam:
|
||||||
sp_opt_inout ident type
|
sp_opt_inout sp_init_param ident type
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_pcontext *spc= lex->spcont;
|
sp_pcontext *spc= lex->spcont;
|
||||||
|
|
||||||
if (spc->find_pvar(&$2, TRUE))
|
if (spc->find_pvar(&$3, TRUE))
|
||||||
{
|
{
|
||||||
my_error(ER_SP_DUP_PARAM, MYF(0), $2.str);
|
my_error(ER_SP_DUP_PARAM, MYF(0), $3.str);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
spc->push_pvar(&$2, (enum enum_field_types)$3,
|
sp_pvar_t *pvar= spc->push_pvar(&$3, (enum enum_field_types)$4,
|
||||||
(sp_param_mode_t)$1);
|
(sp_param_mode_t)$1);
|
||||||
|
|
||||||
|
if (lex->sphead->fill_field_definition(YYTHD, lex,
|
||||||
|
(enum enum_field_types) $4,
|
||||||
|
&pvar->field_def))
|
||||||
|
{
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
pvar->field_def.field_name= pvar->name.str;
|
||||||
|
pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1618,45 +1632,60 @@ sp_decls:
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_decl:
|
sp_decl:
|
||||||
DECLARE_SYM sp_decl_idents type
|
DECLARE_SYM sp_decl_idents
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
|
|
||||||
lex->sphead->reset_lex(YYTHD);
|
lex->sphead->reset_lex(YYTHD);
|
||||||
lex->spcont->declare_var_boundary($2);
|
lex->spcont->declare_var_boundary($2);
|
||||||
}
|
}
|
||||||
|
type
|
||||||
sp_opt_default
|
sp_opt_default
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_pcontext *ctx= lex->spcont;
|
sp_pcontext *pctx= lex->spcont;
|
||||||
uint max= ctx->context_pvars();
|
uint num_vars= pctx->context_pvars();
|
||||||
enum enum_field_types type= (enum enum_field_types)$3;
|
enum enum_field_types var_type= (enum enum_field_types) $4;
|
||||||
Item *it= $5;
|
Item *dflt_value_item= $5;
|
||||||
bool has_default= (it != NULL);
|
create_field *create_field_op;
|
||||||
|
|
||||||
for (uint i = max-$2 ; i < max ; i++)
|
if (!dflt_value_item)
|
||||||
{
|
{
|
||||||
sp_instr_set *in;
|
dflt_value_item= new Item_null();
|
||||||
uint off= ctx->pvar_context2index(i);
|
/* QQ Set to the var_type with null_value? */
|
||||||
|
|
||||||
ctx->set_type(off, type);
|
|
||||||
if (! has_default)
|
|
||||||
it= new Item_null(); /* QQ Set to the type with null_value? */
|
|
||||||
in = new sp_instr_set(lex->sphead->instructions(),
|
|
||||||
ctx,
|
|
||||||
off,
|
|
||||||
it, type, lex,
|
|
||||||
(i == max - 1));
|
|
||||||
|
|
||||||
/*
|
|
||||||
The last instruction is assigned to be responsible for
|
|
||||||
freeing LEX.
|
|
||||||
*/
|
|
||||||
lex->sphead->add_instr(in);
|
|
||||||
ctx->set_default(off, it);
|
|
||||||
}
|
}
|
||||||
ctx->declare_var_boundary(0);
|
|
||||||
|
for (uint i = num_vars-$2 ; i < num_vars ; i++)
|
||||||
|
{
|
||||||
|
uint var_idx= pctx->pvar_context2index(i);
|
||||||
|
sp_pvar_t *pvar= pctx->find_pvar(var_idx);
|
||||||
|
|
||||||
|
if (!pvar)
|
||||||
|
YYABORT;
|
||||||
|
|
||||||
|
pvar->type= var_type;
|
||||||
|
pvar->dflt= dflt_value_item;
|
||||||
|
|
||||||
|
if (lex->sphead->fill_field_definition(YYTHD, lex, var_type,
|
||||||
|
&pvar->field_def))
|
||||||
|
{
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pvar->field_def.field_name= pvar->name.str;
|
||||||
|
pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
|
||||||
|
|
||||||
|
/* The last instruction is responsible for freeing LEX. */
|
||||||
|
|
||||||
|
lex->sphead->add_instr(
|
||||||
|
new sp_instr_set(lex->sphead->instructions(), pctx, var_idx,
|
||||||
|
dflt_value_item, var_type, lex,
|
||||||
|
(i == num_vars - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pctx->declare_var_boundary(0);
|
||||||
lex->sphead->restore_lex(YYTHD);
|
lex->sphead->restore_lex(YYTHD);
|
||||||
|
|
||||||
$$.vars= $2;
|
$$.vars= $2;
|
||||||
$$.conds= $$.hndlrs= $$.curs= 0;
|
$$.conds= $$.hndlrs= $$.curs= 0;
|
||||||
}
|
}
|
||||||
|
@ -1879,6 +1908,8 @@ sp_hcond:
|
||||||
sp_decl_idents:
|
sp_decl_idents:
|
||||||
ident
|
ident
|
||||||
{
|
{
|
||||||
|
/* NOTE: field definition is filled in sp_decl section. */
|
||||||
|
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_pcontext *spc= lex->spcont;
|
sp_pcontext *spc= lex->spcont;
|
||||||
|
|
||||||
|
@ -1892,6 +1923,8 @@ sp_decl_idents:
|
||||||
}
|
}
|
||||||
| sp_decl_idents ',' ident
|
| sp_decl_idents ',' ident
|
||||||
{
|
{
|
||||||
|
/* NOTE: field definition is filled in sp_decl section. */
|
||||||
|
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_pcontext *spc= lex->spcont;
|
sp_pcontext *spc= lex->spcont;
|
||||||
|
|
||||||
|
@ -1969,8 +2002,8 @@ sp_proc_stmt:
|
||||||
{
|
{
|
||||||
sp_instr_freturn *i;
|
sp_instr_freturn *i;
|
||||||
|
|
||||||
i= new sp_instr_freturn(sp->instructions(), lex->spcont,
|
i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3,
|
||||||
$3, sp->m_returns, lex);
|
sp->m_return_field_def.sql_type, lex);
|
||||||
sp->add_instr(i);
|
sp->add_instr(i);
|
||||||
sp->m_flags|= sp_head::HAS_RETURN;
|
sp->m_flags|= sp_head::HAS_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -1986,25 +2019,27 @@ sp_proc_stmt:
|
||||||
{ Lex->sphead->reset_lex(YYTHD); }
|
{ Lex->sphead->reset_lex(YYTHD); }
|
||||||
expr WHEN_SYM
|
expr WHEN_SYM
|
||||||
{
|
{
|
||||||
/* We "fake" this by using an anonymous variable which we
|
|
||||||
set to the expression. Note that all WHENs are evaluate
|
|
||||||
at the same frame level, so we then know that it's the
|
|
||||||
top-most variable in the frame. */
|
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
uint offset= lex->spcont->current_pvars();
|
sp_head *sp= lex->sphead;
|
||||||
sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(),
|
sp_pcontext *parsing_ctx= lex->spcont;
|
||||||
lex->spcont, offset, $3,
|
int case_expr_id= parsing_ctx->register_case_expr();
|
||||||
MYSQL_TYPE_STRING, lex, TRUE);
|
|
||||||
LEX_STRING dummy={(char*)"", 0};
|
if (parsing_ctx->push_case_expr_id(case_expr_id))
|
||||||
|
YYABORT;
|
||||||
lex->spcont->push_pvar(&dummy, MYSQL_TYPE_STRING, sp_param_in);
|
|
||||||
lex->sphead->add_instr(i);
|
sp->add_instr(
|
||||||
lex->sphead->m_flags|= sp_head::IN_SIMPLE_CASE;
|
new sp_instr_set_case_expr(sp->instructions(),
|
||||||
lex->sphead->restore_lex(YYTHD);
|
parsing_ctx,
|
||||||
|
case_expr_id,
|
||||||
|
$3,
|
||||||
|
lex));
|
||||||
|
|
||||||
|
sp->m_flags|= sp_head::IN_SIMPLE_CASE;
|
||||||
|
sp->restore_lex(YYTHD);
|
||||||
}
|
}
|
||||||
sp_case END CASE_SYM
|
sp_case END CASE_SYM
|
||||||
{
|
{
|
||||||
Lex->spcont->pop_pvar();
|
Lex->spcont->pop_case_expr_id();
|
||||||
}
|
}
|
||||||
| sp_labeled_control
|
| sp_labeled_control
|
||||||
{}
|
{}
|
||||||
|
@ -2315,20 +2350,20 @@ sp_case:
|
||||||
i= new sp_instr_jump_if_not(ip, ctx, $2, lex);
|
i= new sp_instr_jump_if_not(ip, ctx, $2, lex);
|
||||||
else
|
else
|
||||||
{ /* Simple case: <caseval> = <whenval> */
|
{ /* Simple case: <caseval> = <whenval> */
|
||||||
LEX_STRING ivar;
|
|
||||||
|
|
||||||
ivar.str= (char *)"_tmp_";
|
Item_case_expr *var;
|
||||||
ivar.length= 5;
|
Item *expr;
|
||||||
Item_splocal *var= new Item_splocal(ivar,
|
|
||||||
ctx->current_pvars()-1);
|
var= new Item_case_expr(ctx->get_current_case_expr_id());
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if (var)
|
if (var)
|
||||||
var->owner= sp;
|
var->m_sp= sp;
|
||||||
#endif
|
#endif
|
||||||
Item *expr= new Item_func_eq(var, $2);
|
|
||||||
|
expr= new Item_func_eq(var, $2);
|
||||||
|
|
||||||
i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
|
i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
|
||||||
lex->variables_used= 1;
|
|
||||||
}
|
}
|
||||||
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
|
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
|
||||||
sp->add_instr(i);
|
sp->add_instr(i);
|
||||||
|
@ -4401,11 +4436,6 @@ optimize:
|
||||||
OPTIMIZE opt_no_write_to_binlog table_or_tables
|
OPTIMIZE opt_no_write_to_binlog table_or_tables
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
if (lex->sphead)
|
|
||||||
{
|
|
||||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "OPTIMIZE TABLE");
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
lex->sql_command = SQLCOM_OPTIMIZE;
|
lex->sql_command = SQLCOM_OPTIMIZE;
|
||||||
lex->no_write_to_binlog= $2;
|
lex->no_write_to_binlog= $2;
|
||||||
lex->check_opt.init();
|
lex->check_opt.init();
|
||||||
|
@ -5024,11 +5054,9 @@ simple_expr:
|
||||||
{
|
{
|
||||||
if ($3->is_splocal())
|
if ($3->is_splocal())
|
||||||
{
|
{
|
||||||
LEX_STRING *name;
|
|
||||||
Item_splocal *il= static_cast<Item_splocal *>($3);
|
Item_splocal *il= static_cast<Item_splocal *>($3);
|
||||||
|
|
||||||
name= il->my_name(NULL);
|
my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
|
||||||
my_error(ER_WRONG_COLUMN_NAME, MYF(0), name->str);
|
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
$$= new Item_default_value(Lex->current_context(), $3);
|
$$= new Item_default_value(Lex->current_context(), $3);
|
||||||
|
@ -5803,10 +5831,8 @@ join_table:
|
||||||
{
|
{
|
||||||
YYERROR_UNLESS($1 && ($$=$3));
|
YYERROR_UNLESS($1 && ($$=$3));
|
||||||
/* Change the current name resolution context to a local context. */
|
/* Change the current name resolution context to a local context. */
|
||||||
Name_resolution_context *on_context;
|
if (push_new_name_resolution_context(YYTHD, $1, $3))
|
||||||
if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
|
|
||||||
YYABORT;
|
YYABORT;
|
||||||
Lex->push_context(on_context);
|
|
||||||
}
|
}
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
|
@ -5818,10 +5844,8 @@ join_table:
|
||||||
{
|
{
|
||||||
YYERROR_UNLESS($1 && ($$=$3));
|
YYERROR_UNLESS($1 && ($$=$3));
|
||||||
/* Change the current name resolution context to a local context. */
|
/* Change the current name resolution context to a local context. */
|
||||||
Name_resolution_context *on_context;
|
if (push_new_name_resolution_context(YYTHD, $1, $3))
|
||||||
if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
|
|
||||||
YYABORT;
|
YYABORT;
|
||||||
Lex->push_context(on_context);
|
|
||||||
}
|
}
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
|
@ -5848,10 +5872,8 @@ join_table:
|
||||||
ON
|
ON
|
||||||
{
|
{
|
||||||
/* Change the current name resolution context to a local context. */
|
/* Change the current name resolution context to a local context. */
|
||||||
Name_resolution_context *on_context;
|
if (push_new_name_resolution_context(YYTHD, $1, $5))
|
||||||
if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
|
|
||||||
YYABORT;
|
YYABORT;
|
||||||
Lex->push_context(on_context);
|
|
||||||
}
|
}
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
|
@ -5881,10 +5903,8 @@ join_table:
|
||||||
ON
|
ON
|
||||||
{
|
{
|
||||||
/* Change the current name resolution context to a local context. */
|
/* Change the current name resolution context to a local context. */
|
||||||
Name_resolution_context *on_context;
|
if (push_new_name_resolution_context(YYTHD, $1, $5))
|
||||||
if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
|
|
||||||
YYABORT;
|
YYABORT;
|
||||||
Lex->push_context(on_context);
|
|
||||||
}
|
}
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
|
@ -5945,10 +5965,9 @@ table_factor:
|
||||||
ON
|
ON
|
||||||
{
|
{
|
||||||
/* Change the current name resolution context to a local context. */
|
/* Change the current name resolution context to a local context. */
|
||||||
Name_resolution_context *on_context;
|
if (push_new_name_resolution_context(YYTHD, $3, $7))
|
||||||
if (!(on_context= make_join_on_context(YYTHD,$3,$7)))
|
|
||||||
YYABORT;
|
YYABORT;
|
||||||
Lex->push_context(on_context);
|
|
||||||
}
|
}
|
||||||
expr '}'
|
expr '}'
|
||||||
{
|
{
|
||||||
|
@ -6505,7 +6524,7 @@ select_var_ident:
|
||||||
var_list.push_back(var= new my_var($1,1,t->offset,t->type));
|
var_list.push_back(var= new my_var($1,1,t->offset,t->type));
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if (var)
|
if (var)
|
||||||
var->owner= lex->sphead;
|
var->sp= lex->sphead;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7816,11 +7835,12 @@ simple_ident:
|
||||||
{
|
{
|
||||||
/* We're compiling a stored procedure and found a variable */
|
/* We're compiling a stored procedure and found a variable */
|
||||||
Item_splocal *splocal;
|
Item_splocal *splocal;
|
||||||
splocal= new Item_splocal($1, spv->offset, lex->tok_start_prev -
|
splocal= new Item_splocal($1, spv->offset, spv->type,
|
||||||
|
lex->tok_start_prev -
|
||||||
lex->sphead->m_tmp_query);
|
lex->sphead->m_tmp_query);
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if (splocal)
|
if (splocal)
|
||||||
splocal->owner= lex->sphead;
|
splocal->m_sp= lex->sphead;
|
||||||
#endif
|
#endif
|
||||||
$$ = (Item*) splocal;
|
$$ = (Item*) splocal;
|
||||||
lex->variables_used= 1;
|
lex->variables_used= 1;
|
||||||
|
|
110
sql/table.cc
110
sql/table.cc
|
@ -3080,60 +3080,6 @@ GRANT_INFO *Natural_join_column::grant()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
|
|
||||||
/*
|
|
||||||
Check the access rights for the current join column.
|
|
||||||
columns.
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Natural_join_column::check_grants()
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Check the access rights to a column from a natural join in a generic
|
|
||||||
way that hides the heterogeneity of the column representation - whether
|
|
||||||
it is a view or a stored table colum.
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
FALSE The column can be accessed
|
|
||||||
TRUE There are no access rights to all equivalent columns
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool
|
|
||||||
Natural_join_column::check_grants(THD *thd, const char *name, uint length)
|
|
||||||
{
|
|
||||||
GRANT_INFO *grant;
|
|
||||||
const char *db_name;
|
|
||||||
const char *table_name;
|
|
||||||
Security_context *save_security_ctx= thd->security_ctx;
|
|
||||||
Security_context *new_sctx= table_ref->security_ctx;
|
|
||||||
bool res;
|
|
||||||
|
|
||||||
if (view_field)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(table_field == NULL);
|
|
||||||
grant= &(table_ref->grant);
|
|
||||||
db_name= table_ref->view_db.str;
|
|
||||||
table_name= table_ref->view_name.str;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(table_field && view_field == NULL);
|
|
||||||
grant= &(table_ref->table->grant);
|
|
||||||
db_name= table_ref->table->s->db.str;
|
|
||||||
table_name= table_ref->table->s->table_name.str;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_sctx)
|
|
||||||
thd->security_ctx= new_sctx;
|
|
||||||
res= check_grant_column(thd, grant, db_name, table_name, name, length);
|
|
||||||
thd->security_ctx= save_security_ctx;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void Field_iterator_view::set(TABLE_LIST *table)
|
void Field_iterator_view::set(TABLE_LIST *table)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table->field_translation);
|
DBUG_ASSERT(table->field_translation);
|
||||||
|
@ -3176,8 +3122,9 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
|
||||||
if (view->schema_table_reformed)
|
if (view->schema_table_reformed)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
In case of SHOW command (schema_table_reformed set) all items are
|
Translation table items are always Item_fields and already fixed
|
||||||
fixed
|
('mysql_schema_table' function). So we can return directly the
|
||||||
|
field. This case happens only for 'show & where' commands.
|
||||||
*/
|
*/
|
||||||
DBUG_ASSERT(field && field->fixed);
|
DBUG_ASSERT(field && field->fixed);
|
||||||
DBUG_RETURN(field);
|
DBUG_RETURN(field);
|
||||||
|
@ -3209,21 +3156,14 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
|
||||||
void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
|
void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table_ref->join_columns);
|
DBUG_ASSERT(table_ref->join_columns);
|
||||||
delete column_ref_it;
|
column_ref_it.init(*(table_ref->join_columns));
|
||||||
|
cur_column_ref= column_ref_it++;
|
||||||
/*
|
|
||||||
TODO: try not to allocate new iterator every time. If we have to,
|
|
||||||
then check for out of memory condition.
|
|
||||||
*/
|
|
||||||
column_ref_it= new List_iterator_fast<Natural_join_column>
|
|
||||||
(*(table_ref->join_columns));
|
|
||||||
cur_column_ref= (*column_ref_it)++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Field_iterator_natural_join::next()
|
void Field_iterator_natural_join::next()
|
||||||
{
|
{
|
||||||
cur_column_ref= (*column_ref_it)++;
|
cur_column_ref= column_ref_it++;
|
||||||
DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
|
DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
|
||||||
cur_column_ref->table_ref->table ==
|
cur_column_ref->table_ref->table ==
|
||||||
cur_column_ref->table_field->table);
|
cur_column_ref->table_field->table);
|
||||||
|
@ -3350,7 +3290,6 @@ GRANT_INFO *Field_iterator_table_ref::grant()
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
Field_iterator_table_ref::get_or_create_column_ref()
|
Field_iterator_table_ref::get_or_create_column_ref()
|
||||||
thd [in] pointer to current thread
|
|
||||||
is_created [out] set to TRUE if the column was created,
|
is_created [out] set to TRUE if the column was created,
|
||||||
FALSE if we return an already created colum
|
FALSE if we return an already created colum
|
||||||
|
|
||||||
|
@ -3363,7 +3302,7 @@ GRANT_INFO *Field_iterator_table_ref::grant()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Natural_join_column *
|
Natural_join_column *
|
||||||
Field_iterator_table_ref::get_or_create_column_ref(THD *thd, bool *is_created)
|
Field_iterator_table_ref::get_or_create_column_ref(bool *is_created)
|
||||||
{
|
{
|
||||||
Natural_join_column *nj_col;
|
Natural_join_column *nj_col;
|
||||||
|
|
||||||
|
@ -3397,6 +3336,41 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, bool *is_created)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return an existing reference to a column of a natural/using join.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
Field_iterator_table_ref::get_natural_column_ref()
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The method should be called in contexts where it is expected that
|
||||||
|
all natural join columns are already created, and that the column
|
||||||
|
being retrieved is a Natural_join_column.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
# Pointer to a column of a natural join (or its operand)
|
||||||
|
NULL No memory to allocate the column
|
||||||
|
*/
|
||||||
|
|
||||||
|
Natural_join_column *
|
||||||
|
Field_iterator_table_ref::get_natural_column_ref()
|
||||||
|
{
|
||||||
|
Natural_join_column *nj_col;
|
||||||
|
|
||||||
|
DBUG_ASSERT(field_it == &natural_join_it);
|
||||||
|
/*
|
||||||
|
The field belongs to a NATURAL join, therefore the column reference was
|
||||||
|
already created via one of the two constructor calls above. In this case
|
||||||
|
we just return the already created column reference.
|
||||||
|
*/
|
||||||
|
nj_col= natural_join_it.column_ref();
|
||||||
|
DBUG_ASSERT(nj_col &&
|
||||||
|
(!nj_col->table_field ||
|
||||||
|
nj_col->table_ref->table == nj_col->table_field->table));
|
||||||
|
return nj_col;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Instansiate templates
|
** Instansiate templates
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
12
sql/table.h
12
sql/table.h
|
@ -432,9 +432,6 @@ public:
|
||||||
const char *table_name();
|
const char *table_name();
|
||||||
const char *db_name();
|
const char *db_name();
|
||||||
GRANT_INFO *grant();
|
GRANT_INFO *grant();
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
bool check_grants(THD *thd, const char *name, uint length);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -760,11 +757,11 @@ public:
|
||||||
|
|
||||||
class Field_iterator_natural_join: public Field_iterator
|
class Field_iterator_natural_join: public Field_iterator
|
||||||
{
|
{
|
||||||
List_iterator_fast<Natural_join_column> *column_ref_it;
|
List_iterator_fast<Natural_join_column> column_ref_it;
|
||||||
Natural_join_column *cur_column_ref;
|
Natural_join_column *cur_column_ref;
|
||||||
public:
|
public:
|
||||||
Field_iterator_natural_join() :column_ref_it(NULL), cur_column_ref(NULL) {}
|
Field_iterator_natural_join() :cur_column_ref(NULL) {}
|
||||||
~Field_iterator_natural_join() { delete column_ref_it; }
|
~Field_iterator_natural_join() {}
|
||||||
void set(TABLE_LIST *table);
|
void set(TABLE_LIST *table);
|
||||||
void next();
|
void next();
|
||||||
bool end_of_fields() { return !cur_column_ref; }
|
bool end_of_fields() { return !cur_column_ref; }
|
||||||
|
@ -811,7 +808,8 @@ public:
|
||||||
GRANT_INFO *grant();
|
GRANT_INFO *grant();
|
||||||
Item *create_item(THD *thd) { return field_it->create_item(thd); }
|
Item *create_item(THD *thd) { return field_it->create_item(thd); }
|
||||||
Field *field() { return field_it->field(); }
|
Field *field() { return field_it->field(); }
|
||||||
Natural_join_column *get_or_create_column_ref(THD *thd, bool *is_created);
|
Natural_join_column *get_or_create_column_ref(bool *is_created);
|
||||||
|
Natural_join_column *get_natural_column_ref();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-
|
/*-
|
||||||
* $Id: LICENSE,v 11.12 2004/03/30 20:49:44 bostic Exp $
|
* $Id: LICENSE,v 12.1 2005/06/16 20:20:10 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
The following is the license that applies to this copy of the Berkeley DB
|
The following is the license that applies to this copy of the Berkeley DB
|
||||||
|
@ -10,7 +10,7 @@ the Web at http://www.sleepycat.com.
|
||||||
|
|
||||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1990-2004
|
* Copyright (c) 1990-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -24,13 +24,12 @@ top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
bdb_build = build_unix
|
bdb_build = build_unix
|
||||||
files = LICENSE Makefile Makefile.in README
|
files = LICENSE Makefile Makefile.in README
|
||||||
subdirs = btree build_vxworks build_win32 clib common cxx db dbinc \
|
subdirs = btree build_win32 clib common cxx db dbinc \
|
||||||
dbinc_auto db185 db_archive db_checkpoint db_deadlock db_dump \
|
dbinc_auto db185 db_archive db_checkpoint db_deadlock db_dump \
|
||||||
db_dump185 db_load db_printlog db_recover db_stat db_upgrade \
|
db_dump185 db_hotbackup db_load db_printlog db_recover db_stat db_upgrade \
|
||||||
db_verify dbm dbreg dist env examples_c examples_cxx fileops hash \
|
db_verify dbm dbreg dist env fileops hash \
|
||||||
hsearch hmac include java libdb_java lock log mp mutex os os_vxworks \
|
hsearch hmac include lock log mp mutex os \
|
||||||
os_win32 perl.BerkeleyDB perl.DB_File qam rep rpc_client rpc_server tcl \
|
os_win32 qam rep txn xa sequence
|
||||||
test txn xa sequence
|
|
||||||
|
|
||||||
@SET_MAKE@
|
@SET_MAKE@
|
||||||
|
|
||||||
|
|
2348
storage/bdb/btree/bt_compact.c
Normal file
2348
storage/bdb/btree/bt_compact.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: bt_compare.c,v 11.20 2004/02/21 15:54:44 bostic Exp $
|
* $Id: bt_compare.c,v 12.1 2005/06/16 20:20:13 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_conv.c,v 11.15 2004/01/28 03:35:48 bostic Exp $
|
* $Id: bt_conv.c,v 12.2 2005/06/16 20:20:13 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -88,7 +88,7 @@ __bam_mswap(pg)
|
||||||
|
|
||||||
p = (u_int8_t *)pg + sizeof(DBMETA);
|
p = (u_int8_t *)pg + sizeof(DBMETA);
|
||||||
|
|
||||||
SWAP32(p); /* maxkey */
|
p += sizeof(u_int32_t); /* unused */
|
||||||
SWAP32(p); /* minkey */
|
SWAP32(p); /* minkey */
|
||||||
SWAP32(p); /* re_len */
|
SWAP32(p); /* re_len */
|
||||||
SWAP32(p); /* re_pad */
|
SWAP32(p); /* re_pad */
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_curadj.c,v 11.37 2004/03/13 14:11:33 bostic Exp $
|
* $Id: bt_curadj.c,v 12.3 2005/07/20 16:50:45 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -35,14 +35,14 @@ static int __bam_opd_cursor __P((DB *, DBC *, db_pgno_t, u_int32_t, u_int32_t));
|
||||||
* Update the cursors when items are deleted and when already deleted
|
* Update the cursors when items are deleted and when already deleted
|
||||||
* items are overwritten. Return the number of relevant cursors found.
|
* items are overwritten. Return the number of relevant cursors found.
|
||||||
*
|
*
|
||||||
* PUBLIC: int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int));
|
* PUBLIC: int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int, int *));
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
__bam_ca_delete(dbp, pgno, indx, delete)
|
__bam_ca_delete(dbp, pgno, indx, delete, countp)
|
||||||
DB *dbp;
|
DB *dbp;
|
||||||
db_pgno_t pgno;
|
db_pgno_t pgno;
|
||||||
u_int32_t indx;
|
u_int32_t indx;
|
||||||
int delete;
|
int delete, *countp;
|
||||||
{
|
{
|
||||||
BTREE_CURSOR *cp;
|
BTREE_CURSOR *cp;
|
||||||
DB *ldbp;
|
DB *ldbp;
|
||||||
|
@ -63,11 +63,11 @@ __bam_ca_delete(dbp, pgno, indx, delete)
|
||||||
* Each cursor is single-threaded, so we only need to lock the
|
* Each cursor is single-threaded, so we only need to lock the
|
||||||
* list of DBs and then the list of cursors in each DB.
|
* list of DBs and then the list of cursors in each DB.
|
||||||
*/
|
*/
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
for (count = 0, ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (count = 0, ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
cp = (BTREE_CURSOR *)dbc->internal;
|
cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
|
@ -92,23 +92,26 @@ __bam_ca_delete(dbp, pgno, indx, delete)
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
|
|
||||||
return (count);
|
if (countp != NULL)
|
||||||
|
*countp = count;
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __ram_ca_delete --
|
* __ram_ca_delete --
|
||||||
* Return the number of relevant cursors.
|
* Return if any relevant cursors found.
|
||||||
*
|
*
|
||||||
* PUBLIC: int __ram_ca_delete __P((DB *, db_pgno_t));
|
* PUBLIC: int __ram_ca_delete __P((DB *, db_pgno_t, int *));
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
__ram_ca_delete(dbp, root_pgno)
|
__ram_ca_delete(dbp, root_pgno, foundp)
|
||||||
DB *dbp;
|
DB *dbp;
|
||||||
db_pgno_t root_pgno;
|
db_pgno_t root_pgno;
|
||||||
|
int *foundp;
|
||||||
{
|
{
|
||||||
DB *ldbp;
|
DB *ldbp;
|
||||||
DBC *dbc;
|
DBC *dbc;
|
||||||
|
@ -121,19 +124,21 @@ __ram_ca_delete(dbp, root_pgno)
|
||||||
/*
|
/*
|
||||||
* Review the cursors. See the comment in __bam_ca_delete().
|
* Review the cursors. See the comment in __bam_ca_delete().
|
||||||
*/
|
*/
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
found == 0 && ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
found == 0 && ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
found == 0 && dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
|
found == 0 && dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
|
||||||
if (dbc->internal->root == root_pgno)
|
if (dbc->internal->root == root_pgno)
|
||||||
found = 1;
|
found = 1;
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
return (found);
|
|
||||||
|
*foundp = found;
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -166,11 +171,11 @@ __bam_ca_di(my_dbc, pgno, indx, adjust)
|
||||||
* Adjust the cursors. See the comment in __bam_ca_delete().
|
* Adjust the cursors. See the comment in __bam_ca_delete().
|
||||||
*/
|
*/
|
||||||
found = 0;
|
found = 0;
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
if (dbc->dbtype == DB_RECNO)
|
if (dbc->dbtype == DB_RECNO)
|
||||||
|
@ -188,9 +193,9 @@ __bam_ca_di(my_dbc, pgno, indx, adjust)
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
|
|
||||||
if (found != 0 && DBC_LOGGING(my_dbc)) {
|
if (found != 0 && DBC_LOGGING(my_dbc)) {
|
||||||
if ((ret = __bam_curadj_log(dbp, my_dbc->txn, &lsn, 0,
|
if ((ret = __bam_curadj_log(dbp, my_dbc->txn, &lsn, 0,
|
||||||
|
@ -289,11 +294,11 @@ __bam_ca_dup(my_dbc, first, fpgno, fi, tpgno, ti)
|
||||||
* Adjust the cursors. See the comment in __bam_ca_delete().
|
* Adjust the cursors. See the comment in __bam_ca_delete().
|
||||||
*/
|
*/
|
||||||
found = 0;
|
found = 0;
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
loop: MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
/* Find cursors pointing to this record. */
|
/* Find cursors pointing to this record. */
|
||||||
|
@ -308,7 +313,7 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
||||||
if (orig_cp->opd != NULL)
|
if (orig_cp->opd != NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
/* [#8032]
|
/* [#8032]
|
||||||
DB_ASSERT(!STD_LOCKING(dbc) ||
|
DB_ASSERT(!STD_LOCKING(dbc) ||
|
||||||
orig_cp->lock_mode != DB_LOCK_NG);
|
orig_cp->lock_mode != DB_LOCK_NG);
|
||||||
|
@ -321,9 +326,9 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
||||||
/* We released the mutex to get a cursor, start over. */
|
/* We released the mutex to get a cursor, start over. */
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
|
|
||||||
if (found != 0 && DBC_LOGGING(my_dbc)) {
|
if (found != 0 && DBC_LOGGING(my_dbc)) {
|
||||||
if ((ret = __bam_curadj_log(dbp, my_dbc->txn,
|
if ((ret = __bam_curadj_log(dbp, my_dbc->txn,
|
||||||
|
@ -359,11 +364,11 @@ __bam_ca_undodup(dbp, first, fpgno, fi, ti)
|
||||||
/*
|
/*
|
||||||
* Adjust the cursors. See the comment in __bam_ca_delete().
|
* Adjust the cursors. See the comment in __bam_ca_delete().
|
||||||
*/
|
*/
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
loop: MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
orig_cp = (BTREE_CURSOR *)dbc->internal;
|
orig_cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
|
@ -377,11 +382,10 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
||||||
*/
|
*/
|
||||||
if (orig_cp->pgno != fpgno ||
|
if (orig_cp->pgno != fpgno ||
|
||||||
orig_cp->indx != first ||
|
orig_cp->indx != first ||
|
||||||
orig_cp->opd == NULL ||
|
orig_cp->opd == NULL || ((BTREE_CURSOR *)
|
||||||
((BTREE_CURSOR *)orig_cp->opd->internal)->indx
|
orig_cp->opd->internal)->indx != ti)
|
||||||
!= ti)
|
|
||||||
continue;
|
continue;
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
if ((ret = __db_c_close(orig_cp->opd)) != 0)
|
if ((ret = __db_c_close(orig_cp->opd)) != 0)
|
||||||
return (ret);
|
return (ret);
|
||||||
orig_cp->opd = NULL;
|
orig_cp->opd = NULL;
|
||||||
|
@ -392,9 +396,9 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
||||||
*/
|
*/
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -425,11 +429,11 @@ __bam_ca_rsplit(my_dbc, fpgno, tpgno)
|
||||||
* Adjust the cursors. See the comment in __bam_ca_delete().
|
* Adjust the cursors. See the comment in __bam_ca_delete().
|
||||||
*/
|
*/
|
||||||
found = 0;
|
found = 0;
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
if (dbc->dbtype == DB_RECNO)
|
if (dbc->dbtype == DB_RECNO)
|
||||||
|
@ -444,9 +448,9 @@ __bam_ca_rsplit(my_dbc, fpgno, tpgno)
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
|
|
||||||
if (found != 0 && DBC_LOGGING(my_dbc)) {
|
if (found != 0 && DBC_LOGGING(my_dbc)) {
|
||||||
if ((ret = __bam_curadj_log(dbp, my_dbc->txn,
|
if ((ret = __bam_curadj_log(dbp, my_dbc->txn,
|
||||||
|
@ -493,11 +497,11 @@ __bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft)
|
||||||
* records split to the left page.
|
* records split to the left page.
|
||||||
*/
|
*/
|
||||||
found = 0;
|
found = 0;
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
if (dbc->dbtype == DB_RECNO)
|
if (dbc->dbtype == DB_RECNO)
|
||||||
|
@ -519,9 +523,9 @@ __bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
|
|
||||||
if (found != 0 && DBC_LOGGING(my_dbc)) {
|
if (found != 0 && DBC_LOGGING(my_dbc)) {
|
||||||
if ((ret = __bam_curadj_log(dbp,
|
if ((ret = __bam_curadj_log(dbp,
|
||||||
|
@ -540,10 +544,10 @@ __bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft)
|
||||||
* left and the right pages.
|
* left and the right pages.
|
||||||
* Called only during undo processing.
|
* Called only during undo processing.
|
||||||
*
|
*
|
||||||
* PUBLIC: void __bam_ca_undosplit __P((DB *,
|
* PUBLIC: int __bam_ca_undosplit __P((DB *,
|
||||||
* PUBLIC: db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t));
|
* PUBLIC: db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t));
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
__bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx)
|
__bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx)
|
||||||
DB *dbp;
|
DB *dbp;
|
||||||
db_pgno_t frompgno, topgno, lpgno;
|
db_pgno_t frompgno, topgno, lpgno;
|
||||||
|
@ -562,11 +566,11 @@ __bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx)
|
||||||
* When backing out a split, we move the cursor back
|
* When backing out a split, we move the cursor back
|
||||||
* to the original offset and bump it by the split_indx.
|
* to the original offset and bump it by the split_indx.
|
||||||
*/
|
*/
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
if (dbc->dbtype == DB_RECNO)
|
if (dbc->dbtype == DB_RECNO)
|
||||||
|
@ -578,7 +582,9 @@ __bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx)
|
||||||
} else if (cp->pgno == lpgno)
|
} else if (cp->pgno == lpgno)
|
||||||
cp->pgno = frompgno;
|
cp->pgno = frompgno;
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_cursor.c,v 11.190 2004/09/22 21:46:32 ubell Exp $
|
* $Id: bt_cursor.c,v 12.7 2005/08/08 14:27:59 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -26,10 +26,8 @@ static int __bam_bulk __P((DBC *, DBT *, u_int32_t));
|
||||||
static int __bam_c_close __P((DBC *, db_pgno_t, int *));
|
static int __bam_c_close __P((DBC *, db_pgno_t, int *));
|
||||||
static int __bam_c_del __P((DBC *));
|
static int __bam_c_del __P((DBC *));
|
||||||
static int __bam_c_destroy __P((DBC *));
|
static int __bam_c_destroy __P((DBC *));
|
||||||
static int __bam_c_first __P((DBC *));
|
|
||||||
static int __bam_c_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
|
static int __bam_c_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
|
||||||
static int __bam_c_getstack __P((DBC *));
|
static int __bam_c_getstack __P((DBC *));
|
||||||
static int __bam_c_last __P((DBC *));
|
|
||||||
static int __bam_c_next __P((DBC *, int, int));
|
static int __bam_c_next __P((DBC *, int, int));
|
||||||
static int __bam_c_physdel __P((DBC *));
|
static int __bam_c_physdel __P((DBC *));
|
||||||
static int __bam_c_prev __P((DBC *));
|
static int __bam_c_prev __P((DBC *));
|
||||||
|
@ -68,21 +66,6 @@ static int __bam_isopd __P((DBC *, db_pgno_t *));
|
||||||
ret = __memp_fget(__mpf, &(fpgno), 0, &(pagep)); \
|
ret = __memp_fget(__mpf, &(fpgno), 0, &(pagep)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#undef ACQUIRE_COUPLE
|
|
||||||
#define ACQUIRE_COUPLE(dbc, mode, lpgno, lock, fpgno, pagep, ret) do { \
|
|
||||||
DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \
|
|
||||||
if ((pagep) != NULL) { \
|
|
||||||
ret = __memp_fput(__mpf, pagep, 0); \
|
|
||||||
pagep = NULL; \
|
|
||||||
} else \
|
|
||||||
ret = 0; \
|
|
||||||
if ((ret) == 0 && STD_LOCKING(dbc)) \
|
|
||||||
ret = __db_lget(dbc, \
|
|
||||||
LCK_COUPLE_ALWAYS, lpgno, mode, 0, &(lock)); \
|
|
||||||
if ((ret) == 0) \
|
|
||||||
ret = __memp_fget(__mpf, &(fpgno), 0, &(pagep)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Acquire a new page/lock for a cursor. */
|
/* Acquire a new page/lock for a cursor. */
|
||||||
#undef ACQUIRE_CUR
|
#undef ACQUIRE_CUR
|
||||||
#define ACQUIRE_CUR(dbc, mode, p, ret) do { \
|
#define ACQUIRE_CUR(dbc, mode, p, ret) do { \
|
||||||
|
@ -96,23 +79,6 @@ static int __bam_isopd __P((DBC *, db_pgno_t *));
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
|
||||||
* Acquire a new page/lock for a cursor and release the previous.
|
|
||||||
* This is typically used when descending a tree and we do not
|
|
||||||
* want to hold the interior nodes locked.
|
|
||||||
*/
|
|
||||||
#undef ACQUIRE_CUR_COUPLE
|
|
||||||
#define ACQUIRE_CUR_COUPLE(dbc, mode, p, ret) do { \
|
|
||||||
BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \
|
|
||||||
if (p != __cp->pgno) \
|
|
||||||
__cp->pgno = PGNO_INVALID; \
|
|
||||||
ACQUIRE_COUPLE(dbc, mode, p, __cp->lock, p, __cp->page, ret); \
|
|
||||||
if ((ret) == 0) { \
|
|
||||||
__cp->pgno = p; \
|
|
||||||
__cp->lock_mode = (mode); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Acquire a write lock if we don't already have one.
|
* Acquire a write lock if we don't already have one.
|
||||||
*
|
*
|
||||||
|
@ -196,11 +162,11 @@ __bam_c_init(dbc, dbtype)
|
||||||
|
|
||||||
/* Allocate/initialize the internal structure. */
|
/* Allocate/initialize the internal structure. */
|
||||||
if (dbc->internal == NULL && (ret =
|
if (dbc->internal == NULL && (ret =
|
||||||
__os_malloc(dbenv, sizeof(BTREE_CURSOR), &dbc->internal)) != 0)
|
__os_calloc(dbenv, 1, sizeof(BTREE_CURSOR), &dbc->internal)) != 0)
|
||||||
return (ret);
|
return (ret);
|
||||||
|
|
||||||
/* Initialize methods. */
|
/* Initialize methods. */
|
||||||
dbc->c_close = __db_c_close;
|
dbc->c_close = __db_c_close_pp;
|
||||||
dbc->c_count = __db_c_count_pp;
|
dbc->c_count = __db_c_count_pp;
|
||||||
dbc->c_del = __db_c_del_pp;
|
dbc->c_del = __db_c_del_pp;
|
||||||
dbc->c_dup = __db_c_dup_pp;
|
dbc->c_dup = __db_c_dup_pp;
|
||||||
|
@ -257,8 +223,11 @@ __bam_c_refresh(dbc)
|
||||||
LOCK_INIT(cp->lock);
|
LOCK_INIT(cp->lock);
|
||||||
cp->lock_mode = DB_LOCK_NG;
|
cp->lock_mode = DB_LOCK_NG;
|
||||||
|
|
||||||
cp->sp = cp->csp = cp->stack;
|
if (cp->sp == NULL) {
|
||||||
cp->esp = cp->stack + sizeof(cp->stack) / sizeof(cp->stack[0]);
|
cp->sp = cp->stack;
|
||||||
|
cp->esp = cp->stack + sizeof(cp->stack) / sizeof(cp->stack[0]);
|
||||||
|
}
|
||||||
|
BT_STK_CLR(cp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The btree leaf page data structures require that two key/data pairs
|
* The btree leaf page data structures require that two key/data pairs
|
||||||
|
@ -308,7 +277,7 @@ __bam_c_close(dbc, root_pgno, rmroot)
|
||||||
DBC *dbc_opd, *dbc_c;
|
DBC *dbc_opd, *dbc_c;
|
||||||
DB_MPOOLFILE *mpf;
|
DB_MPOOLFILE *mpf;
|
||||||
PAGE *h;
|
PAGE *h;
|
||||||
int cdb_lock, ret;
|
int cdb_lock, count, ret;
|
||||||
|
|
||||||
dbp = dbc->dbp;
|
dbp = dbc->dbp;
|
||||||
mpf = dbp->mpf;
|
mpf = dbp->mpf;
|
||||||
|
@ -378,22 +347,28 @@ __bam_c_close(dbc, root_pgno, rmroot)
|
||||||
dbc_c = dbc;
|
dbc_c = dbc;
|
||||||
switch (dbc->dbtype) {
|
switch (dbc->dbtype) {
|
||||||
case DB_BTREE: /* Case #1, #3. */
|
case DB_BTREE: /* Case #1, #3. */
|
||||||
if (__bam_ca_delete(dbp, cp->pgno, cp->indx, 1) == 0)
|
if ((ret = __bam_ca_delete(
|
||||||
|
dbp, cp->pgno, cp->indx, 1, &count)) != 0)
|
||||||
|
goto err;
|
||||||
|
if (count == 0)
|
||||||
goto lock;
|
goto lock;
|
||||||
goto done;
|
goto done;
|
||||||
case DB_RECNO:
|
case DB_RECNO:
|
||||||
if (!F_ISSET(dbc, DBC_OPD)) /* Case #1. */
|
if (!F_ISSET(dbc, DBC_OPD)) /* Case #1. */
|
||||||
goto done;
|
goto done;
|
||||||
/* Case #3. */
|
/* Case #3. */
|
||||||
if (__ram_ca_delete(dbp, cp->root) == 0)
|
if ((ret = __ram_ca_delete(dbp, cp->root, &count)) != 0)
|
||||||
|
goto err;
|
||||||
|
if (count == 0)
|
||||||
goto lock;
|
goto lock;
|
||||||
goto done;
|
goto done;
|
||||||
case DB_HASH:
|
case DB_HASH:
|
||||||
case DB_QUEUE:
|
case DB_QUEUE:
|
||||||
case DB_UNKNOWN:
|
case DB_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
return (__db_unknown_type(dbp->dbenv,
|
ret = __db_unknown_type(dbp->dbenv,
|
||||||
"__bam_c_close", dbc->dbtype));
|
"__bam_c_close", dbc->dbtype);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,20 +389,26 @@ __bam_c_close(dbc, root_pgno, rmroot)
|
||||||
dbc_c = dbc_opd;
|
dbc_c = dbc_opd;
|
||||||
switch (dbc_opd->dbtype) {
|
switch (dbc_opd->dbtype) {
|
||||||
case DB_BTREE:
|
case DB_BTREE:
|
||||||
if (__bam_ca_delete(
|
if ((ret = __bam_ca_delete(
|
||||||
dbp, cp_opd->pgno, cp_opd->indx, 1) == 0)
|
dbp, cp_opd->pgno, cp_opd->indx, 1, &count)) != 0)
|
||||||
|
goto err;
|
||||||
|
if (count == 0)
|
||||||
goto lock;
|
goto lock;
|
||||||
goto done;
|
goto done;
|
||||||
case DB_RECNO:
|
case DB_RECNO:
|
||||||
if (__ram_ca_delete(dbp, cp_opd->root) == 0)
|
if ((ret =
|
||||||
|
__ram_ca_delete(dbp, cp_opd->root, &count)) != 0)
|
||||||
|
goto err;
|
||||||
|
if (count == 0)
|
||||||
goto lock;
|
goto lock;
|
||||||
goto done;
|
goto done;
|
||||||
case DB_HASH:
|
case DB_HASH:
|
||||||
case DB_QUEUE:
|
case DB_QUEUE:
|
||||||
case DB_UNKNOWN:
|
case DB_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
return (__db_unknown_type(
|
ret = __db_unknown_type(
|
||||||
dbp->dbenv, "__bam_c_close", dbc->dbtype));
|
dbp->dbenv, "__bam_c_close", dbc->dbtype);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -588,8 +569,14 @@ static int
|
||||||
__bam_c_destroy(dbc)
|
__bam_c_destroy(dbc)
|
||||||
DBC *dbc;
|
DBC *dbc;
|
||||||
{
|
{
|
||||||
|
BTREE_CURSOR *cp;
|
||||||
|
|
||||||
|
cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
|
|
||||||
/* Discard the structures. */
|
/* Discard the structures. */
|
||||||
__os_free(dbc->dbp->dbenv, dbc->internal);
|
if (cp->sp != cp->stack)
|
||||||
|
__os_free(dbc->dbp->dbenv, cp->sp);
|
||||||
|
__os_free(dbc->dbp->dbenv, cp);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -693,7 +680,7 @@ __bam_c_del(dbc)
|
||||||
BTREE_CURSOR *cp;
|
BTREE_CURSOR *cp;
|
||||||
DB *dbp;
|
DB *dbp;
|
||||||
DB_MPOOLFILE *mpf;
|
DB_MPOOLFILE *mpf;
|
||||||
int ret, t_ret;
|
int count, ret, t_ret;
|
||||||
|
|
||||||
dbp = dbc->dbp;
|
dbp = dbc->dbp;
|
||||||
mpf = dbp->mpf;
|
mpf = dbp->mpf;
|
||||||
|
@ -760,9 +747,12 @@ err: /*
|
||||||
|
|
||||||
cp->page = NULL;
|
cp->page = NULL;
|
||||||
|
|
||||||
/* Update the cursors last, after all chance of failure is past. */
|
/*
|
||||||
|
* Update the cursors last, after all chance of recoverable failure
|
||||||
|
* is past.
|
||||||
|
*/
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
(void)__bam_ca_delete(dbp, cp->pgno, cp->indx, 1);
|
ret = __bam_ca_delete(dbp, cp->pgno, cp->indx, 1, &count);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -846,7 +836,8 @@ __bam_c_get(dbc, key, data, flags, pgnop)
|
||||||
break;
|
break;
|
||||||
case DB_FIRST:
|
case DB_FIRST:
|
||||||
newopd = 1;
|
newopd = 1;
|
||||||
if ((ret = __bam_c_first(dbc)) != 0)
|
if ((ret = __bam_c_search(dbc,
|
||||||
|
PGNO_INVALID, NULL, flags, &exact)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
break;
|
break;
|
||||||
case DB_GET_BOTH:
|
case DB_GET_BOTH:
|
||||||
|
@ -910,13 +901,15 @@ __bam_c_get(dbc, key, data, flags, pgnop)
|
||||||
break;
|
break;
|
||||||
case DB_LAST:
|
case DB_LAST:
|
||||||
newopd = 1;
|
newopd = 1;
|
||||||
if ((ret = __bam_c_last(dbc)) != 0)
|
if ((ret = __bam_c_search(dbc,
|
||||||
|
PGNO_INVALID, NULL, flags, &exact)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
break;
|
break;
|
||||||
case DB_NEXT:
|
case DB_NEXT:
|
||||||
newopd = 1;
|
newopd = 1;
|
||||||
if (cp->pgno == PGNO_INVALID) {
|
if (cp->pgno == PGNO_INVALID) {
|
||||||
if ((ret = __bam_c_first(dbc)) != 0)
|
if ((ret = __bam_c_search(dbc,
|
||||||
|
PGNO_INVALID, NULL, DB_FIRST, &exact)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
} else
|
} else
|
||||||
if ((ret = __bam_c_next(dbc, 1, 0)) != 0)
|
if ((ret = __bam_c_next(dbc, 1, 0)) != 0)
|
||||||
|
@ -933,7 +926,8 @@ __bam_c_get(dbc, key, data, flags, pgnop)
|
||||||
case DB_NEXT_NODUP:
|
case DB_NEXT_NODUP:
|
||||||
newopd = 1;
|
newopd = 1;
|
||||||
if (cp->pgno == PGNO_INVALID) {
|
if (cp->pgno == PGNO_INVALID) {
|
||||||
if ((ret = __bam_c_first(dbc)) != 0)
|
if ((ret = __bam_c_search(dbc,
|
||||||
|
PGNO_INVALID, NULL, DB_FIRST, &exact)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
} else
|
} else
|
||||||
do {
|
do {
|
||||||
|
@ -944,7 +938,8 @@ __bam_c_get(dbc, key, data, flags, pgnop)
|
||||||
case DB_PREV:
|
case DB_PREV:
|
||||||
newopd = 1;
|
newopd = 1;
|
||||||
if (cp->pgno == PGNO_INVALID) {
|
if (cp->pgno == PGNO_INVALID) {
|
||||||
if ((ret = __bam_c_last(dbc)) != 0)
|
if ((ret = __bam_c_search(dbc,
|
||||||
|
PGNO_INVALID, NULL, DB_LAST, &exact)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
} else
|
} else
|
||||||
if ((ret = __bam_c_prev(dbc)) != 0)
|
if ((ret = __bam_c_prev(dbc)) != 0)
|
||||||
|
@ -953,7 +948,8 @@ __bam_c_get(dbc, key, data, flags, pgnop)
|
||||||
case DB_PREV_NODUP:
|
case DB_PREV_NODUP:
|
||||||
newopd = 1;
|
newopd = 1;
|
||||||
if (cp->pgno == PGNO_INVALID) {
|
if (cp->pgno == PGNO_INVALID) {
|
||||||
if ((ret = __bam_c_last(dbc)) != 0)
|
if ((ret = __bam_c_search(dbc,
|
||||||
|
PGNO_INVALID, NULL, DB_LAST, &exact)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
} else
|
} else
|
||||||
do {
|
do {
|
||||||
|
@ -2136,99 +2132,6 @@ __bam_c_writelock(dbc)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* __bam_c_first --
|
|
||||||
* Return the first record.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
__bam_c_first(dbc)
|
|
||||||
DBC *dbc;
|
|
||||||
{
|
|
||||||
BTREE_CURSOR *cp;
|
|
||||||
db_pgno_t pgno;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
cp = (BTREE_CURSOR *)dbc->internal;
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
/* Walk down the left-hand side of the tree. */
|
|
||||||
for (pgno = cp->root;;) {
|
|
||||||
ACQUIRE_CUR_COUPLE(dbc, DB_LOCK_READ, pgno, ret);
|
|
||||||
if (ret != 0)
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
/* If we find a leaf page, we're done. */
|
|
||||||
if (ISLEAF(cp->page))
|
|
||||||
break;
|
|
||||||
|
|
||||||
pgno = GET_BINTERNAL(dbc->dbp, cp->page, 0)->pgno;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we want a write lock instead of a read lock, get it now. */
|
|
||||||
if (F_ISSET(dbc, DBC_RMW)) {
|
|
||||||
ACQUIRE_WRITE_LOCK(dbc, ret);
|
|
||||||
if (ret != 0)
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
cp->indx = 0;
|
|
||||||
|
|
||||||
/* If on an empty page or a deleted record, move to the next one. */
|
|
||||||
if (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))
|
|
||||||
if ((ret = __bam_c_next(dbc, 0, 0)) != 0)
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* __bam_c_last --
|
|
||||||
* Return the last record.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
__bam_c_last(dbc)
|
|
||||||
DBC *dbc;
|
|
||||||
{
|
|
||||||
BTREE_CURSOR *cp;
|
|
||||||
db_pgno_t pgno;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
cp = (BTREE_CURSOR *)dbc->internal;
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
/* Walk down the right-hand side of the tree. */
|
|
||||||
for (pgno = cp->root;;) {
|
|
||||||
ACQUIRE_CUR_COUPLE(dbc, DB_LOCK_READ, pgno, ret);
|
|
||||||
if (ret != 0)
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
/* If we find a leaf page, we're done. */
|
|
||||||
if (ISLEAF(cp->page))
|
|
||||||
break;
|
|
||||||
|
|
||||||
pgno = GET_BINTERNAL(dbc->dbp, cp->page,
|
|
||||||
NUM_ENT(cp->page) - O_INDX)->pgno;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we want a write lock instead of a read lock, get it now. */
|
|
||||||
if (F_ISSET(dbc, DBC_RMW)) {
|
|
||||||
ACQUIRE_WRITE_LOCK(dbc, ret);
|
|
||||||
if (ret != 0)
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
cp->indx = NUM_ENT(cp->page) == 0 ? 0 :
|
|
||||||
NUM_ENT(cp->page) -
|
|
||||||
(TYPE(cp->page) == P_LBTREE ? P_INDX : O_INDX);
|
|
||||||
|
|
||||||
/* If on an empty page or a deleted record, move to the previous one. */
|
|
||||||
if (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))
|
|
||||||
if ((ret = __bam_c_prev(dbc)) != 0)
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __bam_c_next --
|
* __bam_c_next --
|
||||||
* Move to the next record.
|
* Move to the next record.
|
||||||
|
@ -2398,6 +2301,12 @@ __bam_c_search(dbc, root_pgno, key, flags, exactp)
|
||||||
return (ret);
|
return (ret);
|
||||||
|
|
||||||
switch (flags) {
|
switch (flags) {
|
||||||
|
case DB_FIRST:
|
||||||
|
sflags = (F_ISSET(dbc, DBC_RMW) ? S_WRITE : S_READ) | S_MIN;
|
||||||
|
goto search;
|
||||||
|
case DB_LAST:
|
||||||
|
sflags = (F_ISSET(dbc, DBC_RMW) ? S_WRITE : S_READ) | S_MAX;
|
||||||
|
goto search;
|
||||||
case DB_SET_RECNO:
|
case DB_SET_RECNO:
|
||||||
if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0)
|
if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0)
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -2575,7 +2484,6 @@ search: if ((ret = __bam_search(dbc, root_pgno,
|
||||||
default:
|
default:
|
||||||
return (__db_unknown_flag(dbp->dbenv, "__bam_c_search", flags));
|
return (__db_unknown_flag(dbp->dbenv, "__bam_c_search", flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the cursor from the stack. */
|
/* Initialize the cursor from the stack. */
|
||||||
cp->page = cp->csp->page;
|
cp->page = cp->csp->page;
|
||||||
cp->pgno = cp->csp->page->pgno;
|
cp->pgno = cp->csp->page->pgno;
|
||||||
|
@ -2583,6 +2491,16 @@ search: if ((ret = __bam_search(dbc, root_pgno,
|
||||||
cp->lock = cp->csp->lock;
|
cp->lock = cp->csp->lock;
|
||||||
cp->lock_mode = cp->csp->lock_mode;
|
cp->lock_mode = cp->csp->lock_mode;
|
||||||
|
|
||||||
|
/* If on an empty page or a deleted record, move to the next one. */
|
||||||
|
if (flags == DB_FIRST &&
|
||||||
|
(NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc)))
|
||||||
|
if ((ret = __bam_c_next(dbc, 0, 0)) != 0)
|
||||||
|
return (ret);
|
||||||
|
if (flags == DB_LAST &&
|
||||||
|
(NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc)))
|
||||||
|
if ((ret = __bam_c_prev(dbc)) != 0)
|
||||||
|
return (ret);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2597,15 +2515,10 @@ __bam_c_physdel(dbc)
|
||||||
BTREE_CURSOR *cp;
|
BTREE_CURSOR *cp;
|
||||||
DB *dbp;
|
DB *dbp;
|
||||||
DBT key;
|
DBT key;
|
||||||
DB_LOCK lock;
|
int delete_page, empty_page, exact, ret;
|
||||||
DB_MPOOLFILE *mpf;
|
|
||||||
PAGE *h;
|
|
||||||
db_pgno_t pgno;
|
|
||||||
int delete_page, empty_page, exact, level, ret;
|
|
||||||
|
|
||||||
dbp = dbc->dbp;
|
dbp = dbc->dbp;
|
||||||
memset(&key, 0, sizeof(DBT));
|
memset(&key, 0, sizeof(DBT));
|
||||||
mpf = dbp->mpf;
|
|
||||||
cp = (BTREE_CURSOR *)dbc->internal;
|
cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
delete_page = empty_page = ret = 0;
|
delete_page = empty_page = ret = 0;
|
||||||
|
|
||||||
|
@ -2683,91 +2596,7 @@ __bam_c_physdel(dbc)
|
||||||
if (!delete_page)
|
if (!delete_page)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
ret = __bam_search(dbc, PGNO_INVALID, &key, S_DEL, 0, NULL, &exact);
|
||||||
* Call __bam_search to reacquire the empty leaf page, but this time
|
|
||||||
* get both the leaf page and it's parent, locked. Jump back up the
|
|
||||||
* tree, until we have the top pair of pages that we want to delete.
|
|
||||||
* Once we have the top page that we want to delete locked, lock the
|
|
||||||
* underlying pages and check to make sure they're still empty. If
|
|
||||||
* they are, delete them.
|
|
||||||
*/
|
|
||||||
for (level = LEAFLEVEL;; ++level) {
|
|
||||||
/* Acquire a page and its parent, locked. */
|
|
||||||
if ((ret = __bam_search(dbc, PGNO_INVALID,
|
|
||||||
&key, S_WRPAIR, level, NULL, &exact)) != 0)
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we reach the root or the parent page isn't going to be
|
|
||||||
* empty when we delete one record, stop.
|
|
||||||
*/
|
|
||||||
h = cp->csp[-1].page;
|
|
||||||
if (h->pgno == cp->root || NUM_ENT(h) != 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Discard the stack, retaining no locks. */
|
|
||||||
(void)__bam_stkrel(dbc, STK_NOLOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Move the stack pointer one after the last entry, we may be about
|
|
||||||
* to push more items onto the page stack.
|
|
||||||
*/
|
|
||||||
++cp->csp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cp->csp[-2].page is now the parent page, which we may or may not be
|
|
||||||
* going to delete, and cp->csp[-1].page is the first page we know we
|
|
||||||
* are going to delete. Walk down the chain of pages, acquiring pages
|
|
||||||
* until we've acquired a leaf page. Generally, this shouldn't happen;
|
|
||||||
* we should only see a single internal page with one item and a single
|
|
||||||
* leaf page with no items. The scenario where we could see something
|
|
||||||
* else is if reverse splits were turned off for awhile and then turned
|
|
||||||
* back on. That could result in all sorts of strangeness, e.g., empty
|
|
||||||
* pages in the tree, trees that looked like linked lists, and so on.
|
|
||||||
*
|
|
||||||
* !!!
|
|
||||||
* Sheer paranoia: if we find any pages that aren't going to be emptied
|
|
||||||
* by the delete, someone else added an item while we were walking the
|
|
||||||
* tree, and we discontinue the delete. Shouldn't be possible, but we
|
|
||||||
* check regardless.
|
|
||||||
*/
|
|
||||||
for (h = cp->csp[-1].page;;) {
|
|
||||||
if (ISLEAF(h)) {
|
|
||||||
if (NUM_ENT(h) != 0)
|
|
||||||
break;
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
if (NUM_ENT(h) != 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the next page, write lock it and push it onto the stack.
|
|
||||||
* We know it's index 0, because it can only have one element.
|
|
||||||
*/
|
|
||||||
switch (TYPE(h)) {
|
|
||||||
case P_IBTREE:
|
|
||||||
pgno = GET_BINTERNAL(dbp, h, 0)->pgno;
|
|
||||||
break;
|
|
||||||
case P_IRECNO:
|
|
||||||
pgno = GET_RINTERNAL(dbp, h, 0)->pgno;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (__db_pgfmt(dbp->dbenv, PGNO(h)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret =
|
|
||||||
__db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &lock)) != 0)
|
|
||||||
break;
|
|
||||||
if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
|
|
||||||
break;
|
|
||||||
BT_STK_PUSH(dbp->dbenv, cp, h, 0, lock, DB_LOCK_WRITE, ret);
|
|
||||||
if (ret != 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust the cursor stack to reference the last page on the stack. */
|
|
||||||
BT_STK_POP(cp);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If everything worked, delete the stack, otherwise, release the
|
* If everything worked, delete the stack, otherwise, release the
|
||||||
|
@ -2776,7 +2605,7 @@ __bam_c_physdel(dbc)
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
DISCARD_CUR(dbc, ret);
|
DISCARD_CUR(dbc, ret);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = __bam_dpages(dbc, cp->sp);
|
ret = __bam_dpages(dbc, 1, 0);
|
||||||
else
|
else
|
||||||
(void)__bam_stkrel(dbc, 0);
|
(void)__bam_stkrel(dbc, 0);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: bt_delete.c,v 11.49 2004/02/27 12:38:28 bostic Exp $
|
* $Id: bt_delete.c,v 12.13 2005/10/20 18:14:59 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -220,12 +220,13 @@ __bam_adjindx(dbc, h, indx, indx_copy, is_insert)
|
||||||
* __bam_dpages --
|
* __bam_dpages --
|
||||||
* Delete a set of locked pages.
|
* Delete a set of locked pages.
|
||||||
*
|
*
|
||||||
* PUBLIC: int __bam_dpages __P((DBC *, EPG *));
|
* PUBLIC: int __bam_dpages __P((DBC *, int, int));
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
__bam_dpages(dbc, stack_epg)
|
__bam_dpages(dbc, use_top, update)
|
||||||
DBC *dbc;
|
DBC *dbc;
|
||||||
EPG *stack_epg;
|
int use_top;
|
||||||
|
int update;
|
||||||
{
|
{
|
||||||
BTREE_CURSOR *cp;
|
BTREE_CURSOR *cp;
|
||||||
BINTERNAL *bi;
|
BINTERNAL *bi;
|
||||||
|
@ -233,7 +234,7 @@ __bam_dpages(dbc, stack_epg)
|
||||||
DBT a, b;
|
DBT a, b;
|
||||||
DB_LOCK c_lock, p_lock;
|
DB_LOCK c_lock, p_lock;
|
||||||
DB_MPOOLFILE *mpf;
|
DB_MPOOLFILE *mpf;
|
||||||
EPG *epg;
|
EPG *epg, *save_sp, *stack_epg;
|
||||||
PAGE *child, *parent;
|
PAGE *child, *parent;
|
||||||
db_indx_t nitems;
|
db_indx_t nitems;
|
||||||
db_pgno_t pgno, root_pgno;
|
db_pgno_t pgno, root_pgno;
|
||||||
|
@ -243,30 +244,27 @@ __bam_dpages(dbc, stack_epg)
|
||||||
dbp = dbc->dbp;
|
dbp = dbc->dbp;
|
||||||
mpf = dbp->mpf;
|
mpf = dbp->mpf;
|
||||||
cp = (BTREE_CURSOR *)dbc->internal;
|
cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
|
nitems = 0;
|
||||||
|
pgno = PGNO_INVALID;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have the entire stack of deletable pages locked.
|
* We have the entire stack of deletable pages locked.
|
||||||
*
|
*
|
||||||
* Btree calls us with a pointer to the beginning of a stack, where
|
* Btree calls us with the first page in the stack is to have a
|
||||||
* the first page in the stack is to have a single item deleted, and
|
* single item deleted, and the rest of the pages are to be removed.
|
||||||
* the rest of the pages are to be removed.
|
|
||||||
*
|
*
|
||||||
* Recno calls us with a pointer into the middle of the stack, where
|
* Recno always has a stack to the root and __bam_merge operations
|
||||||
* the referenced page is to have a single item deleted, and pages
|
* may have unneeded items in the sack. We find the lowest page
|
||||||
* after the stack reference are to be removed.
|
* in the stack that has more than one record in it and start there.
|
||||||
*
|
|
||||||
* First, discard any pages that we don't care about.
|
|
||||||
*/
|
*/
|
||||||
ret = 0;
|
ret = 0;
|
||||||
for (epg = cp->sp; epg < stack_epg; ++epg) {
|
if (use_top)
|
||||||
if ((t_ret = __memp_fput(mpf, epg->page, 0)) != 0 && ret == 0)
|
stack_epg = cp->sp;
|
||||||
ret = t_ret;
|
else
|
||||||
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
|
for (stack_epg = cp->csp; stack_epg > cp->sp; --stack_epg)
|
||||||
ret = t_ret;
|
if (NUM_ENT(stack_epg->page) > 1)
|
||||||
}
|
break;
|
||||||
if (ret != 0)
|
epg = stack_epg;
|
||||||
goto err;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* !!!
|
* !!!
|
||||||
* There is an interesting deadlock situation here. We have to relink
|
* There is an interesting deadlock situation here. We have to relink
|
||||||
|
@ -276,8 +274,9 @@ __bam_dpages(dbc, stack_epg)
|
||||||
* It will deadlock here. Before we unlink the subtree, we relink the
|
* It will deadlock here. Before we unlink the subtree, we relink the
|
||||||
* leaf page chain.
|
* leaf page chain.
|
||||||
*/
|
*/
|
||||||
if ((ret = __bam_relink(dbc, cp->csp->page, NULL)) != 0)
|
if (LEVEL(cp->csp->page) == 1 &&
|
||||||
goto err;
|
(ret = __bam_relink(dbc, cp->csp->page, PGNO_INVALID)) != 0)
|
||||||
|
goto discard;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete the last item that references the underlying pages that are
|
* Delete the last item that references the underlying pages that are
|
||||||
|
@ -288,9 +287,18 @@ __bam_dpages(dbc, stack_epg)
|
||||||
* immediately.
|
* immediately.
|
||||||
*/
|
*/
|
||||||
if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0)
|
if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0)
|
||||||
goto err;
|
goto discard;
|
||||||
if ((ret = __bam_ca_di(dbc, PGNO(epg->page), epg->indx, -1)) != 0)
|
if ((ret = __bam_ca_di(dbc, PGNO(epg->page), epg->indx, -1)) != 0)
|
||||||
goto err;
|
goto discard;
|
||||||
|
|
||||||
|
if (update && epg->indx == 0) {
|
||||||
|
save_sp = cp->csp;
|
||||||
|
cp->csp = epg;
|
||||||
|
ret = __bam_pupdate(dbc, epg->page);
|
||||||
|
cp->csp = save_sp;
|
||||||
|
if (ret != 0)
|
||||||
|
goto discard;
|
||||||
|
}
|
||||||
|
|
||||||
pgno = PGNO(epg->page);
|
pgno = PGNO(epg->page);
|
||||||
nitems = NUM_ENT(epg->page);
|
nitems = NUM_ENT(epg->page);
|
||||||
|
@ -301,6 +309,17 @@ __bam_dpages(dbc, stack_epg)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto err_inc;
|
goto err_inc;
|
||||||
|
|
||||||
|
/* Then, discard any pages that we don't care about. */
|
||||||
|
discard: for (epg = cp->sp; epg < stack_epg; ++epg) {
|
||||||
|
if ((t_ret = __memp_fput(mpf, epg->page, 0)) != 0 && ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
epg->page = NULL;
|
||||||
|
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
}
|
||||||
|
if (ret != 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
/* Free the rest of the pages in the stack. */
|
/* Free the rest of the pages in the stack. */
|
||||||
while (++epg <= cp->csp) {
|
while (++epg <= cp->csp) {
|
||||||
/*
|
/*
|
||||||
|
@ -310,13 +329,24 @@ __bam_dpages(dbc, stack_epg)
|
||||||
* be referenced by a cursor.
|
* be referenced by a cursor.
|
||||||
*/
|
*/
|
||||||
if (NUM_ENT(epg->page) != 0) {
|
if (NUM_ENT(epg->page) != 0) {
|
||||||
DB_ASSERT(NUM_ENT(epg->page) == 1);
|
DB_ASSERT(LEVEL(epg->page) != 1);
|
||||||
|
|
||||||
if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0)
|
if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
/*
|
||||||
|
* Sheer paranoia: if we find any pages that aren't
|
||||||
|
* emptied by the delete, someone else added an item
|
||||||
|
* while we were walking the tree, and we discontinue
|
||||||
|
* the delete. Shouldn't be possible, but we check
|
||||||
|
* regardless.
|
||||||
|
*/
|
||||||
|
if (NUM_ENT(epg->page) != 0)
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = __db_free(dbc, epg->page);
|
ret = __db_free(dbc, epg->page);
|
||||||
|
if (cp->page == epg->page)
|
||||||
|
cp->page = NULL;
|
||||||
epg->page = NULL;
|
epg->page = NULL;
|
||||||
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
|
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
|
||||||
ret = t_ret;
|
ret = t_ret;
|
||||||
|
@ -468,12 +498,13 @@ stop: done = 1;
|
||||||
* __bam_relink --
|
* __bam_relink --
|
||||||
* Relink around a deleted page.
|
* Relink around a deleted page.
|
||||||
*
|
*
|
||||||
* PUBLIC: int __bam_relink __P((DBC *, PAGE *, PAGE **));
|
* PUBLIC: int __bam_relink __P((DBC *, PAGE *, db_pgno_t));
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
__bam_relink(dbc, pagep, new_next)
|
__bam_relink(dbc, pagep, new_pgno)
|
||||||
DBC *dbc;
|
DBC *dbc;
|
||||||
PAGE *pagep, **new_next;
|
PAGE *pagep;
|
||||||
|
db_pgno_t new_pgno;
|
||||||
{
|
{
|
||||||
DB *dbp;
|
DB *dbp;
|
||||||
PAGE *np, *pp;
|
PAGE *np, *pp;
|
||||||
|
@ -519,7 +550,7 @@ __bam_relink(dbc, pagep, new_next)
|
||||||
/* Log the change. */
|
/* Log the change. */
|
||||||
if (DBC_LOGGING(dbc)) {
|
if (DBC_LOGGING(dbc)) {
|
||||||
if ((ret = __bam_relink_log(dbp, dbc->txn, &ret_lsn, 0,
|
if ((ret = __bam_relink_log(dbp, dbc->txn, &ret_lsn, 0,
|
||||||
pagep->pgno, &pagep->lsn, pagep->prev_pgno, plsnp,
|
pagep->pgno, new_pgno, pagep->prev_pgno, plsnp,
|
||||||
pagep->next_pgno, nlsnp)) != 0)
|
pagep->next_pgno, nlsnp)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
} else
|
} else
|
||||||
|
@ -528,33 +559,27 @@ __bam_relink(dbc, pagep, new_next)
|
||||||
np->lsn = ret_lsn;
|
np->lsn = ret_lsn;
|
||||||
if (pp != NULL)
|
if (pp != NULL)
|
||||||
pp->lsn = ret_lsn;
|
pp->lsn = ret_lsn;
|
||||||
pagep->lsn = ret_lsn;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modify and release the two pages.
|
* Modify and release the two pages.
|
||||||
*
|
|
||||||
* !!!
|
|
||||||
* The parameter new_next gets set to the page following the page we
|
|
||||||
* are removing. If there is no following page, then new_next gets
|
|
||||||
* set to NULL.
|
|
||||||
*/
|
*/
|
||||||
if (np != NULL) {
|
if (np != NULL) {
|
||||||
np->prev_pgno = pagep->prev_pgno;
|
if (new_pgno == PGNO_INVALID)
|
||||||
if (new_next == NULL)
|
np->prev_pgno = pagep->prev_pgno;
|
||||||
ret = __memp_fput(mpf, np, DB_MPOOL_DIRTY);
|
else
|
||||||
else {
|
np->prev_pgno = new_pgno;
|
||||||
*new_next = np;
|
ret = __memp_fput(mpf, np, DB_MPOOL_DIRTY);
|
||||||
ret = __memp_fset(mpf, np, DB_MPOOL_DIRTY);
|
|
||||||
}
|
|
||||||
if ((t_ret = __TLPUT(dbc, npl)) != 0 && ret == 0)
|
if ((t_ret = __TLPUT(dbc, npl)) != 0 && ret == 0)
|
||||||
ret = t_ret;
|
ret = t_ret;
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto err;
|
goto err;
|
||||||
} else if (new_next != NULL)
|
}
|
||||||
*new_next = NULL;
|
|
||||||
|
|
||||||
if (pp != NULL) {
|
if (pp != NULL) {
|
||||||
pp->next_pgno = pagep->next_pgno;
|
if (new_pgno == PGNO_INVALID)
|
||||||
|
pp->next_pgno = pagep->next_pgno;
|
||||||
|
else
|
||||||
|
pp->next_pgno = new_pgno;
|
||||||
ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY);
|
ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY);
|
||||||
if ((t_ret = __TLPUT(dbc, ppl)) != 0 && ret == 0)
|
if ((t_ret = __TLPUT(dbc, ppl)) != 0 && ret == 0)
|
||||||
ret = t_ret;
|
ret = t_ret;
|
||||||
|
@ -571,3 +596,48 @@ err: if (np != NULL)
|
||||||
(void)__TLPUT(dbc, ppl);
|
(void)__TLPUT(dbc, ppl);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __bam_pupdate --
|
||||||
|
* Update parent key pointers up the tree.
|
||||||
|
*
|
||||||
|
* PUBLIC: int __bam_pupdate __P((DBC *, PAGE *));
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__bam_pupdate(dbc, lpg)
|
||||||
|
DBC *dbc;
|
||||||
|
PAGE *lpg;
|
||||||
|
{
|
||||||
|
BTREE_CURSOR *cp;
|
||||||
|
DB_ENV *dbenv;
|
||||||
|
EPG *epg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dbenv = dbc->dbp->dbenv;
|
||||||
|
cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the parents up the tree. __bam_pinsert only looks at the
|
||||||
|
* left child if is a leaf page, so we don't need to change it. We
|
||||||
|
* just do a delete and insert; a replace is possible but reusing
|
||||||
|
* pinsert is better.
|
||||||
|
*/
|
||||||
|
for (epg = &cp->csp[-1]; epg >= cp->sp; epg--) {
|
||||||
|
if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0)
|
||||||
|
return (ret);
|
||||||
|
epg->indx--;
|
||||||
|
if ((ret = __bam_pinsert(dbc, epg,
|
||||||
|
lpg, epg[1].page, BPI_NORECNUM)) != 0) {
|
||||||
|
if (ret == DB_NEEDSPLIT) {
|
||||||
|
/* This should not happen. */
|
||||||
|
__db_err(dbenv,
|
||||||
|
"Not enough room in parent: %s: page %lu",
|
||||||
|
dbc->dbp->fname, (u_long)PGNO(epg->page));
|
||||||
|
ret = __db_panic(dbenv, EINVAL);
|
||||||
|
}
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1999-2004
|
* Copyright (c) 1999-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_method.c,v 11.38 2004/09/22 03:31:26 bostic Exp $
|
* $Id: bt_method.c,v 12.2 2005/06/16 20:20:16 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -18,7 +18,6 @@
|
||||||
#include "dbinc/btree.h"
|
#include "dbinc/btree.h"
|
||||||
#include "dbinc/qam.h"
|
#include "dbinc/qam.h"
|
||||||
|
|
||||||
static int __bam_set_bt_maxkey __P((DB *, u_int32_t));
|
|
||||||
static int __bam_set_bt_minkey __P((DB *, u_int32_t));
|
static int __bam_set_bt_minkey __P((DB *, u_int32_t));
|
||||||
static int __bam_set_bt_prefix
|
static int __bam_set_bt_prefix
|
||||||
__P((DB *, size_t(*)(DB *, const DBT *, const DBT *)));
|
__P((DB *, size_t(*)(DB *, const DBT *, const DBT *)));
|
||||||
|
@ -52,7 +51,6 @@ __bam_db_create(dbp)
|
||||||
t->bt_prefix = __bam_defpfx;
|
t->bt_prefix = __bam_defpfx;
|
||||||
|
|
||||||
dbp->set_bt_compare = __bam_set_bt_compare;
|
dbp->set_bt_compare = __bam_set_bt_compare;
|
||||||
dbp->set_bt_maxkey = __bam_set_bt_maxkey;
|
|
||||||
dbp->get_bt_minkey = __bam_get_bt_minkey;
|
dbp->get_bt_minkey = __bam_get_bt_minkey;
|
||||||
dbp->set_bt_minkey = __bam_set_bt_minkey;
|
dbp->set_bt_minkey = __bam_set_bt_minkey;
|
||||||
dbp->set_bt_prefix = __bam_set_bt_prefix;
|
dbp->set_bt_prefix = __bam_set_bt_prefix;
|
||||||
|
@ -208,31 +206,6 @@ __bam_set_bt_compare(dbp, func)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* __bam_set_bt_maxkey --
|
|
||||||
* Set the maximum keys per page.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
__bam_set_bt_maxkey(dbp, bt_maxkey)
|
|
||||||
DB *dbp;
|
|
||||||
u_int32_t bt_maxkey;
|
|
||||||
{
|
|
||||||
BTREE *t;
|
|
||||||
|
|
||||||
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_maxkey");
|
|
||||||
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
|
|
||||||
|
|
||||||
t = dbp->bt_internal;
|
|
||||||
|
|
||||||
if (bt_maxkey < 1) {
|
|
||||||
__db_err(dbp->dbenv, "minimum bt_maxkey value is 1");
|
|
||||||
return (EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
t->bt_maxkey = bt_maxkey;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __db_get_bt_minkey --
|
* __db_get_bt_minkey --
|
||||||
* Get the minimum keys per page.
|
* Get the minimum keys per page.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: bt_open.c,v 11.92 2004/04/29 14:39:47 ubell Exp $
|
* $Id: bt_open.c,v 12.5 2005/09/28 17:44:17 margo Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -311,7 +311,6 @@ __bam_read_root(dbp, txn, base_pgno, flags)
|
||||||
* metadata page will be created/initialized elsewhere.
|
* metadata page will be created/initialized elsewhere.
|
||||||
*/
|
*/
|
||||||
if (meta->dbmeta.magic == DB_BTREEMAGIC) {
|
if (meta->dbmeta.magic == DB_BTREEMAGIC) {
|
||||||
t->bt_maxkey = meta->maxkey;
|
|
||||||
t->bt_minkey = meta->minkey;
|
t->bt_minkey = meta->minkey;
|
||||||
t->re_pad = (int)meta->re_pad;
|
t->re_pad = (int)meta->re_pad;
|
||||||
t->re_len = meta->re_len;
|
t->re_len = meta->re_len;
|
||||||
|
@ -395,7 +394,6 @@ __bam_init_meta(dbp, meta, pgno, lsnp)
|
||||||
memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN);
|
memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN);
|
||||||
|
|
||||||
t = dbp->bt_internal;
|
t = dbp->bt_internal;
|
||||||
meta->maxkey = t->bt_maxkey;
|
|
||||||
meta->minkey = t->bt_minkey;
|
meta->minkey = t->bt_minkey;
|
||||||
meta->re_len = t->re_len;
|
meta->re_len = t->re_len;
|
||||||
meta->re_pad = (u_int32_t)t->re_pad;
|
meta->re_pad = (u_int32_t)t->re_pad;
|
||||||
|
@ -428,7 +426,7 @@ __bam_new_file(dbp, txn, fhp, name)
|
||||||
DBT pdbt;
|
DBT pdbt;
|
||||||
PAGE *root;
|
PAGE *root;
|
||||||
db_pgno_t pgno;
|
db_pgno_t pgno;
|
||||||
int ret;
|
int ret, t_ret;
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
dbenv = dbp->dbenv;
|
dbenv = dbp->dbenv;
|
||||||
|
@ -437,7 +435,7 @@ __bam_new_file(dbp, txn, fhp, name)
|
||||||
meta = NULL;
|
meta = NULL;
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
|
|
||||||
if (name == NULL) {
|
if (F_ISSET(dbp, DB_AM_INMEM)) {
|
||||||
/* Build the meta-data page. */
|
/* Build the meta-data page. */
|
||||||
pgno = PGNO_BASE_MD;
|
pgno = PGNO_BASE_MD;
|
||||||
if ((ret =
|
if ((ret =
|
||||||
|
@ -447,6 +445,9 @@ __bam_new_file(dbp, txn, fhp, name)
|
||||||
__bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
|
__bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
|
||||||
meta->root = 1;
|
meta->root = 1;
|
||||||
meta->dbmeta.last_pgno = 1;
|
meta->dbmeta.last_pgno = 1;
|
||||||
|
if ((ret =
|
||||||
|
__db_log_page(dbp, txn, &lsn, pgno, (PAGE *)meta)) != 0)
|
||||||
|
goto err;
|
||||||
ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
|
ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
|
||||||
meta = NULL;
|
meta = NULL;
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -460,6 +461,9 @@ __bam_new_file(dbp, txn, fhp, name)
|
||||||
P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
|
P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
|
||||||
LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
|
LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
|
||||||
LSN_NOT_LOGGED(root->lsn);
|
LSN_NOT_LOGGED(root->lsn);
|
||||||
|
if ((ret =
|
||||||
|
__db_log_page(dbp, txn, &root->lsn, pgno, root)) != 0)
|
||||||
|
goto err;
|
||||||
ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY);
|
ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY);
|
||||||
root = NULL;
|
root = NULL;
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -509,10 +513,12 @@ __bam_new_file(dbp, txn, fhp, name)
|
||||||
err: if (buf != NULL)
|
err: if (buf != NULL)
|
||||||
__os_free(dbenv, buf);
|
__os_free(dbenv, buf);
|
||||||
else {
|
else {
|
||||||
if (meta != NULL)
|
if (meta != NULL &&
|
||||||
(void)__memp_fput(mpf, meta, 0);
|
(t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
|
||||||
if (root != NULL)
|
ret = t_ret;
|
||||||
(void)__memp_fput(mpf, root, 0);
|
if (root != NULL &&
|
||||||
|
(t_ret = __memp_fput(mpf, root, 0)) != 0 && ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: bt_put.c,v 11.80 2004/10/29 17:33:25 ubell Exp $
|
* $Id: bt_put.c,v 12.10 2005/10/20 18:57:00 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -58,7 +58,9 @@
|
||||||
|
|
||||||
static int __bam_build
|
static int __bam_build
|
||||||
__P((DBC *, u_int32_t, DBT *, PAGE *, u_int32_t, u_int32_t));
|
__P((DBC *, u_int32_t, DBT *, PAGE *, u_int32_t, u_int32_t));
|
||||||
static int __bam_dup_convert __P((DBC *, PAGE *, u_int32_t));
|
static int __bam_dup_check __P((DBC *, u_int32_t,
|
||||||
|
PAGE *, u_int32_t, u_int32_t, db_indx_t *));
|
||||||
|
static int __bam_dup_convert __P((DBC *, PAGE *, u_int32_t, u_int32_t));
|
||||||
static int __bam_ovput
|
static int __bam_ovput
|
||||||
__P((DBC *, u_int32_t, db_pgno_t, PAGE *, u_int32_t, DBT *));
|
__P((DBC *, u_int32_t, db_pgno_t, PAGE *, u_int32_t, DBT *));
|
||||||
static u_int32_t
|
static u_int32_t
|
||||||
|
@ -84,11 +86,12 @@ __bam_iitem(dbc, key, data, op, flags)
|
||||||
DBT bk_hdr, tdbt;
|
DBT bk_hdr, tdbt;
|
||||||
DB_MPOOLFILE *mpf;
|
DB_MPOOLFILE *mpf;
|
||||||
PAGE *h;
|
PAGE *h;
|
||||||
db_indx_t indx;
|
db_indx_t cnt, indx;
|
||||||
u_int32_t data_size, have_bytes, need_bytes, needed;
|
u_int32_t data_size, have_bytes, need_bytes, needed, pages, pagespace;
|
||||||
int cmp, bigkey, bigdata, dupadjust, padrec, replace, ret, was_deleted;
|
int cmp, bigkey, bigdata, dupadjust, padrec, replace, ret, was_deleted;
|
||||||
|
|
||||||
COMPQUIET(bk, NULL);
|
COMPQUIET(bk, NULL);
|
||||||
|
COMPQUIET(cnt, 0);
|
||||||
|
|
||||||
dbp = dbc->dbp;
|
dbp = dbc->dbp;
|
||||||
dbenv = dbp->dbenv;
|
dbenv = dbp->dbenv;
|
||||||
|
@ -217,13 +220,39 @@ __bam_iitem(dbc, key, data, op, flags)
|
||||||
return (__db_unknown_flag(dbenv, "DB->put", op));
|
return (__db_unknown_flag(dbenv, "DB->put", op));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Split the page if there's not enough room. */
|
||||||
* If there's not enough room, or the user has put a ceiling on the
|
|
||||||
* number of keys permitted in the page, split the page.
|
|
||||||
*/
|
|
||||||
if (P_FREESPACE(dbp, h) < needed)
|
if (P_FREESPACE(dbp, h) < needed)
|
||||||
return (DB_NEEDSPLIT);
|
return (DB_NEEDSPLIT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see if we will convert to off page duplicates -- if
|
||||||
|
* so, we'll need a page.
|
||||||
|
*/
|
||||||
|
if (F_ISSET(dbp, DB_AM_DUP) &&
|
||||||
|
TYPE(h) == P_LBTREE && op != DB_KEYFIRST &&
|
||||||
|
P_FREESPACE(dbp, h) - needed <= dbp->pgsize / 2 &&
|
||||||
|
__bam_dup_check(dbc, op, h, indx, needed, &cnt)) {
|
||||||
|
pages = 1;
|
||||||
|
dupadjust = 1;
|
||||||
|
} else
|
||||||
|
pages = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are not using transactions and there is a page limit
|
||||||
|
* set on the file, then figure out if things will fit before
|
||||||
|
* taking action.
|
||||||
|
*/
|
||||||
|
if (dbc->txn == NULL && dbp->mpf->mfp->maxpgno != 0) {
|
||||||
|
pagespace = P_MAXSPACE(dbp, dbp->pgsize);
|
||||||
|
if (bigdata)
|
||||||
|
pages += ((data_size - 1) / pagespace) + 1;
|
||||||
|
if (bigkey)
|
||||||
|
pages += ((key->size - 1) / pagespace) + 1;
|
||||||
|
|
||||||
|
if (pages > (dbp->mpf->mfp->maxpgno - dbp->mpf->mfp->last_pgno))
|
||||||
|
return (__db_space_err(dbp));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The code breaks it up into five cases:
|
* The code breaks it up into five cases:
|
||||||
*
|
*
|
||||||
|
@ -259,7 +288,6 @@ __bam_iitem(dbc, key, data, op, flags)
|
||||||
return (ret);
|
return (ret);
|
||||||
|
|
||||||
indx += 3;
|
indx += 3;
|
||||||
dupadjust = 1;
|
|
||||||
|
|
||||||
cp->indx += 2;
|
cp->indx += 2;
|
||||||
} else {
|
} else {
|
||||||
|
@ -276,7 +304,6 @@ __bam_iitem(dbc, key, data, op, flags)
|
||||||
return (ret);
|
return (ret);
|
||||||
|
|
||||||
++indx;
|
++indx;
|
||||||
dupadjust = 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DB_CURRENT:
|
case DB_CURRENT:
|
||||||
|
@ -287,11 +314,11 @@ __bam_iitem(dbc, key, data, op, flags)
|
||||||
* will try and remove the item because the cursor's delete
|
* will try and remove the item because the cursor's delete
|
||||||
* flag is set.
|
* flag is set.
|
||||||
*/
|
*/
|
||||||
(void)__bam_ca_delete(dbp, PGNO(h), indx, 0);
|
if ((ret = __bam_ca_delete(dbp, PGNO(h), indx, 0, NULL)) != 0)
|
||||||
|
return (ret);
|
||||||
|
|
||||||
if (TYPE(h) == P_LBTREE) {
|
if (TYPE(h) == P_LBTREE) {
|
||||||
++indx;
|
++indx;
|
||||||
dupadjust = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -380,10 +407,9 @@ __bam_iitem(dbc, key, data, op, flags)
|
||||||
* up at least 25% of the space on the page. If it does, move it onto
|
* up at least 25% of the space on the page. If it does, move it onto
|
||||||
* its own page.
|
* its own page.
|
||||||
*/
|
*/
|
||||||
if (dupadjust && P_FREESPACE(dbp, h) <= dbp->pgsize / 2) {
|
if (dupadjust &&
|
||||||
if ((ret = __bam_dup_convert(dbc, h, indx - O_INDX)) != 0)
|
(ret = __bam_dup_convert(dbc, h, indx - O_INDX, cnt)) != 0)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
|
||||||
|
|
||||||
/* If we've modified a recno file, set the flag. */
|
/* If we've modified a recno file, set the flag. */
|
||||||
if (dbc->dbtype == DB_RECNO)
|
if (dbc->dbtype == DB_RECNO)
|
||||||
|
@ -664,26 +690,22 @@ __bam_ritem(dbc, h, indx, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __bam_dup_convert --
|
* __bam_dup_check --
|
||||||
* Check to see if the duplicate set at indx should have its own page.
|
* Check to see if the duplicate set at indx should have its own page.
|
||||||
* If it should, create it.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
__bam_dup_convert(dbc, h, indx)
|
__bam_dup_check(dbc, op, h, indx, sz, cntp)
|
||||||
DBC *dbc;
|
DBC *dbc;
|
||||||
|
u_int32_t op;
|
||||||
PAGE *h;
|
PAGE *h;
|
||||||
u_int32_t indx;
|
u_int32_t indx, sz;
|
||||||
|
db_indx_t *cntp;
|
||||||
{
|
{
|
||||||
BKEYDATA *bk;
|
BKEYDATA *bk;
|
||||||
DB *dbp;
|
DB *dbp;
|
||||||
DBT hdr;
|
db_indx_t cnt, first, *inp;
|
||||||
DB_MPOOLFILE *mpf;
|
|
||||||
PAGE *dp;
|
|
||||||
db_indx_t cnt, cpindx, dindx, first, *inp, sz;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
dbp = dbc->dbp;
|
dbp = dbc->dbp;
|
||||||
mpf = dbp->mpf;
|
|
||||||
inp = P_INP(dbp, h);
|
inp = P_INP(dbp, h);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -695,11 +717,21 @@ __bam_dup_convert(dbc, h, indx)
|
||||||
|
|
||||||
/* Count the key once. */
|
/* Count the key once. */
|
||||||
bk = GET_BKEYDATA(dbp, h, indx);
|
bk = GET_BKEYDATA(dbp, h, indx);
|
||||||
sz = B_TYPE(bk->type) == B_KEYDATA ?
|
sz += B_TYPE(bk->type) == B_KEYDATA ?
|
||||||
BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
|
BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
|
||||||
|
|
||||||
/* Sum up all the data items. */
|
/* Sum up all the data items. */
|
||||||
for (cnt = 0, first = indx;
|
first = indx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Account for the record being inserted. If we are replacing it,
|
||||||
|
* don't count it twice.
|
||||||
|
*
|
||||||
|
* We execute the loop with first == indx to get the size of the
|
||||||
|
* first record.
|
||||||
|
*/
|
||||||
|
cnt = op == DB_CURRENT ? 0 : 1;
|
||||||
|
for (first = indx;
|
||||||
indx < NUM_ENT(h) && inp[first] == inp[indx];
|
indx < NUM_ENT(h) && inp[first] == inp[indx];
|
||||||
++cnt, indx += P_INDX) {
|
++cnt, indx += P_INDX) {
|
||||||
bk = GET_BKEYDATA(dbp, h, indx + O_INDX);
|
bk = GET_BKEYDATA(dbp, h, indx + O_INDX);
|
||||||
|
@ -726,6 +758,36 @@ __bam_dup_convert(dbc, h, indx)
|
||||||
if (sz < dbp->pgsize / 4)
|
if (sz < dbp->pgsize / 4)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
*cntp = cnt;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __bam_dup_convert --
|
||||||
|
* Move a set of duplicates off-page and into their own tree.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
__bam_dup_convert(dbc, h, indx, cnt)
|
||||||
|
DBC *dbc;
|
||||||
|
PAGE *h;
|
||||||
|
u_int32_t indx, cnt;
|
||||||
|
{
|
||||||
|
BKEYDATA *bk;
|
||||||
|
DB *dbp;
|
||||||
|
DBT hdr;
|
||||||
|
DB_MPOOLFILE *mpf;
|
||||||
|
PAGE *dp;
|
||||||
|
db_indx_t cpindx, dindx, first, *inp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dbp = dbc->dbp;
|
||||||
|
mpf = dbp->mpf;
|
||||||
|
inp = P_INP(dbp, h);
|
||||||
|
|
||||||
|
/* Move to the beginning of the dup set. */
|
||||||
|
while (indx > 0 && inp[indx] == inp[indx - P_INDX])
|
||||||
|
indx -= P_INDX;
|
||||||
|
|
||||||
/* Get a new page. */
|
/* Get a new page. */
|
||||||
if ((ret = __db_new(dbc,
|
if ((ret = __db_new(dbc,
|
||||||
dbp->dup_compare == NULL ? P_LRECNO : P_LDUP, &dp)) != 0)
|
dbp->dup_compare == NULL ? P_LRECNO : P_LDUP, &dp)) != 0)
|
||||||
|
@ -739,8 +801,8 @@ __bam_dup_convert(dbc, h, indx)
|
||||||
* we're dealing with.
|
* we're dealing with.
|
||||||
*/
|
*/
|
||||||
memset(&hdr, 0, sizeof(hdr));
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
dindx = first;
|
first = indx;
|
||||||
indx = first;
|
dindx = indx;
|
||||||
cpindx = 0;
|
cpindx = 0;
|
||||||
do {
|
do {
|
||||||
/* Move cursors referencing the old entry to the new entry. */
|
/* Move cursors referencing the old entry to the new entry. */
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_rec.c,v 11.70 2004/09/24 00:43:12 bostic Exp $
|
* $Id: bt_rec.c,v 12.11 2005/10/20 18:57:01 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -58,7 +58,7 @@ __bam_split_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
_lp = lp = np = pp = _rp = rp = NULL;
|
_lp = lp = np = pp = _rp = rp = NULL;
|
||||||
sp = NULL;
|
sp = NULL;
|
||||||
|
|
||||||
REC_INTRO(__bam_split_read, 1);
|
REC_INTRO(__bam_split_read, 1, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are two kinds of splits that we have to recover from. The
|
* There are two kinds of splits that we have to recover from. The
|
||||||
|
@ -96,21 +96,21 @@ redo: if (DB_REDO(op)) {
|
||||||
REC_FGET(mpf, root_pgno, &pp, do_left);
|
REC_FGET(mpf, root_pgno, &pp, do_left);
|
||||||
cmp =
|
cmp =
|
||||||
log_compare(&LSN(pp), &LSN(argp->pg.data));
|
log_compare(&LSN(pp), &LSN(argp->pg.data));
|
||||||
CHECK_LSN(op,
|
CHECK_LSN(dbenv, op,
|
||||||
cmp, &LSN(pp), &LSN(argp->pg.data));
|
cmp, &LSN(pp), &LSN(argp->pg.data));
|
||||||
p_update = cmp == 0;
|
p_update = cmp == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_left: if (lp != NULL) {
|
do_left: if (lp != NULL) {
|
||||||
cmp = log_compare(&LSN(lp), &argp->llsn);
|
cmp = log_compare(&LSN(lp), &argp->llsn);
|
||||||
CHECK_LSN(op, cmp, &LSN(lp), &argp->llsn);
|
CHECK_LSN(dbenv, op, cmp, &LSN(lp), &argp->llsn);
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
l_update = 1;
|
l_update = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rp != NULL) {
|
if (rp != NULL) {
|
||||||
cmp = log_compare(&LSN(rp), &argp->rlsn);
|
cmp = log_compare(&LSN(rp), &argp->rlsn);
|
||||||
CHECK_LSN(op, cmp, &LSN(rp), &argp->rlsn);
|
CHECK_LSN(dbenv, op, cmp, &LSN(rp), &argp->rlsn);
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
r_update = 1;
|
r_update = 1;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ check_next: /*
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cmp = log_compare(&LSN(np), &argp->nlsn);
|
cmp = log_compare(&LSN(np), &argp->nlsn);
|
||||||
CHECK_LSN(op, cmp, &LSN(np), &argp->nlsn);
|
CHECK_LSN(dbenv, op, cmp, &LSN(np), &argp->nlsn);
|
||||||
if (cmp == 0) {
|
if (cmp == 0) {
|
||||||
PREV_PGNO(np) = argp->right;
|
PREV_PGNO(np) = argp->right;
|
||||||
np->lsn = *lsnp;
|
np->lsn = *lsnp;
|
||||||
|
@ -337,12 +337,13 @@ __bam_rsplit_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
DB_MPOOLFILE *mpf;
|
DB_MPOOLFILE *mpf;
|
||||||
PAGE *pagep;
|
PAGE *pagep;
|
||||||
db_pgno_t pgno, root_pgno;
|
db_pgno_t pgno, root_pgno;
|
||||||
|
db_recno_t rcnt;
|
||||||
int cmp_n, cmp_p, modified, ret;
|
int cmp_n, cmp_p, modified, ret;
|
||||||
|
|
||||||
pagep = NULL;
|
pagep = NULL;
|
||||||
COMPQUIET(info, NULL);
|
COMPQUIET(info, NULL);
|
||||||
REC_PRINT(__bam_rsplit_print);
|
REC_PRINT(__bam_rsplit_print);
|
||||||
REC_INTRO(__bam_rsplit_read, 1);
|
REC_INTRO(__bam_rsplit_read, 1, 1);
|
||||||
|
|
||||||
/* Fix the root page. */
|
/* Fix the root page. */
|
||||||
pgno = root_pgno = argp->root_pgno;
|
pgno = root_pgno = argp->root_pgno;
|
||||||
|
@ -361,10 +362,19 @@ __bam_rsplit_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
modified = 0;
|
modified = 0;
|
||||||
cmp_n = log_compare(lsnp, &LSN(pagep));
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
cmp_p = log_compare(&LSN(pagep), &argp->rootlsn);
|
cmp_p = log_compare(&LSN(pagep), &argp->rootlsn);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->rootlsn);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->rootlsn);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/* Need to redo update described. */
|
/*
|
||||||
|
* Copy the new data to the root page. If it is not now a
|
||||||
|
* leaf page we need to restore the record number. We could
|
||||||
|
* try to determine if C_RECNUM was set in the btree, but
|
||||||
|
* that's not really necessary since the field is not used
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
rcnt = RE_NREC(pagep);
|
||||||
memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size);
|
memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size);
|
||||||
|
if (LEVEL(pagep) > LEAFLEVEL)
|
||||||
|
RE_NREC_SET(pagep, rcnt);
|
||||||
pagep->pgno = root_pgno;
|
pagep->pgno = root_pgno;
|
||||||
pagep->lsn = *lsnp;
|
pagep->lsn = *lsnp;
|
||||||
modified = 1;
|
modified = 1;
|
||||||
|
@ -403,7 +413,7 @@ do_page:
|
||||||
(void)__ua_memcpy(©_lsn, &LSN(argp->pgdbt.data), sizeof(DB_LSN));
|
(void)__ua_memcpy(©_lsn, &LSN(argp->pgdbt.data), sizeof(DB_LSN));
|
||||||
cmp_n = log_compare(lsnp, &LSN(pagep));
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
cmp_p = log_compare(&LSN(pagep), ©_lsn);
|
cmp_p = log_compare(&LSN(pagep), ©_lsn);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), ©_lsn);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), ©_lsn);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/* Need to redo update described. */
|
/* Need to redo update described. */
|
||||||
pagep->lsn = *lsnp;
|
pagep->lsn = *lsnp;
|
||||||
|
@ -450,7 +460,7 @@ __bam_adj_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
pagep = NULL;
|
pagep = NULL;
|
||||||
COMPQUIET(info, NULL);
|
COMPQUIET(info, NULL);
|
||||||
REC_PRINT(__bam_adj_print);
|
REC_PRINT(__bam_adj_print);
|
||||||
REC_INTRO(__bam_adj_read, 1);
|
REC_INTRO(__bam_adj_read, 1, 1);
|
||||||
|
|
||||||
/* Get the page; if it never existed and we're undoing, we're done. */
|
/* Get the page; if it never existed and we're undoing, we're done. */
|
||||||
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
||||||
|
@ -468,7 +478,7 @@ __bam_adj_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
modified = 0;
|
modified = 0;
|
||||||
cmp_n = log_compare(lsnp, &LSN(pagep));
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/* Need to redo update described. */
|
/* Need to redo update described. */
|
||||||
if ((ret = __bam_adjindx(dbc,
|
if ((ret = __bam_adjindx(dbc,
|
||||||
|
@ -524,7 +534,7 @@ __bam_cadjust_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
pagep = NULL;
|
pagep = NULL;
|
||||||
COMPQUIET(info, NULL);
|
COMPQUIET(info, NULL);
|
||||||
REC_PRINT(__bam_cadjust_print);
|
REC_PRINT(__bam_cadjust_print);
|
||||||
REC_INTRO(__bam_cadjust_read, 1);
|
REC_INTRO(__bam_cadjust_read, 1, 0);
|
||||||
|
|
||||||
/* Get the page; if it never existed and we're undoing, we're done. */
|
/* Get the page; if it never existed and we're undoing, we're done. */
|
||||||
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
||||||
|
@ -542,7 +552,7 @@ __bam_cadjust_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
modified = 0;
|
modified = 0;
|
||||||
cmp_n = log_compare(lsnp, &LSN(pagep));
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/* Need to redo update described. */
|
/* Need to redo update described. */
|
||||||
if (IS_BTREE_PAGE(pagep)) {
|
if (IS_BTREE_PAGE(pagep)) {
|
||||||
|
@ -613,7 +623,7 @@ __bam_cdel_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
pagep = NULL;
|
pagep = NULL;
|
||||||
COMPQUIET(info, NULL);
|
COMPQUIET(info, NULL);
|
||||||
REC_PRINT(__bam_cdel_print);
|
REC_PRINT(__bam_cdel_print);
|
||||||
REC_INTRO(__bam_cdel_read, 1);
|
REC_INTRO(__bam_cdel_read, 1, 0);
|
||||||
|
|
||||||
/* Get the page; if it never existed and we're undoing, we're done. */
|
/* Get the page; if it never existed and we're undoing, we're done. */
|
||||||
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
||||||
|
@ -631,7 +641,7 @@ __bam_cdel_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
modified = 0;
|
modified = 0;
|
||||||
cmp_n = log_compare(lsnp, &LSN(pagep));
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/* Need to redo update described. */
|
/* Need to redo update described. */
|
||||||
indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0);
|
indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0);
|
||||||
|
@ -644,7 +654,9 @@ __bam_cdel_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0);
|
indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0);
|
||||||
B_DCLR(GET_BKEYDATA(file_dbp, pagep, indx)->type);
|
B_DCLR(GET_BKEYDATA(file_dbp, pagep, indx)->type);
|
||||||
|
|
||||||
(void)__bam_ca_delete(file_dbp, argp->pgno, argp->indx, 0);
|
if ((ret = __bam_ca_delete(
|
||||||
|
file_dbp, argp->pgno, argp->indx, 0, NULL)) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
LSN(pagep) = argp->lsn;
|
LSN(pagep) = argp->lsn;
|
||||||
modified = 1;
|
modified = 1;
|
||||||
|
@ -689,7 +701,7 @@ __bam_repl_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
pagep = NULL;
|
pagep = NULL;
|
||||||
COMPQUIET(info, NULL);
|
COMPQUIET(info, NULL);
|
||||||
REC_PRINT(__bam_repl_print);
|
REC_PRINT(__bam_repl_print);
|
||||||
REC_INTRO(__bam_repl_read, 1);
|
REC_INTRO(__bam_repl_read, 1, 1);
|
||||||
|
|
||||||
/* Get the page; if it never existed and we're undoing, we're done. */
|
/* Get the page; if it never existed and we're undoing, we're done. */
|
||||||
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
||||||
|
@ -708,7 +720,7 @@ __bam_repl_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
modified = 0;
|
modified = 0;
|
||||||
cmp_n = log_compare(lsnp, &LSN(pagep));
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/*
|
/*
|
||||||
* Need to redo update described.
|
* Need to redo update described.
|
||||||
|
@ -799,7 +811,7 @@ __bam_root_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
meta = NULL;
|
meta = NULL;
|
||||||
COMPQUIET(info, NULL);
|
COMPQUIET(info, NULL);
|
||||||
REC_PRINT(__bam_root_print);
|
REC_PRINT(__bam_root_print);
|
||||||
REC_INTRO(__bam_root_read, 0);
|
REC_INTRO(__bam_root_read, 0, 0);
|
||||||
|
|
||||||
if ((ret = __memp_fget(mpf, &argp->meta_pgno, 0, &meta)) != 0) {
|
if ((ret = __memp_fget(mpf, &argp->meta_pgno, 0, &meta)) != 0) {
|
||||||
if (ret != DB_PAGE_NOTFOUND
|
if (ret != DB_PAGE_NOTFOUND
|
||||||
|
@ -816,7 +828,7 @@ __bam_root_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
modified = 0;
|
modified = 0;
|
||||||
cmp_n = log_compare(lsnp, &LSN(meta));
|
cmp_n = log_compare(lsnp, &LSN(meta));
|
||||||
cmp_p = log_compare(&LSN(meta), &argp->meta_lsn);
|
cmp_p = log_compare(&LSN(meta), &argp->meta_lsn);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(meta), &argp->meta_lsn);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(meta), &argp->meta_lsn);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/* Need to redo update described. */
|
/* Need to redo update described. */
|
||||||
meta->root = argp->root_pgno;
|
meta->root = argp->root_pgno;
|
||||||
|
@ -866,7 +878,7 @@ __bam_curadj_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
COMPQUIET(mpf, NULL);
|
COMPQUIET(mpf, NULL);
|
||||||
|
|
||||||
REC_PRINT(__bam_curadj_print);
|
REC_PRINT(__bam_curadj_print);
|
||||||
REC_INTRO(__bam_curadj_read, 0);
|
REC_INTRO(__bam_curadj_read, 0, 1);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (op != DB_TXN_ABORT)
|
if (op != DB_TXN_ABORT)
|
||||||
|
@ -891,8 +903,9 @@ __bam_curadj_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DB_CA_SPLIT:
|
case DB_CA_SPLIT:
|
||||||
__bam_ca_undosplit(file_dbp, argp->from_pgno,
|
if ((ret = __bam_ca_undosplit(file_dbp, argp->from_pgno,
|
||||||
argp->to_pgno, argp->left_pgno, argp->from_indx);
|
argp->to_pgno, argp->left_pgno, argp->from_indx)) != 0)
|
||||||
|
goto out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -928,7 +941,7 @@ __bam_rcuradj_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
rdbc = NULL;
|
rdbc = NULL;
|
||||||
|
|
||||||
REC_PRINT(__bam_rcuradj_print);
|
REC_PRINT(__bam_rcuradj_print);
|
||||||
REC_INTRO(__bam_rcuradj_read, 0);
|
REC_INTRO(__bam_rcuradj_read, 0, 1);
|
||||||
|
|
||||||
ret = t_ret = 0;
|
ret = t_ret = 0;
|
||||||
|
|
||||||
|
@ -1008,7 +1021,7 @@ __bam_relink_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
pagep = NULL;
|
pagep = NULL;
|
||||||
COMPQUIET(info, NULL);
|
COMPQUIET(info, NULL);
|
||||||
REC_PRINT(__bam_relink_print);
|
REC_PRINT(__bam_relink_print);
|
||||||
REC_INTRO(__bam_relink_read, 1);
|
REC_INTRO(__bam_relink_read, 1, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are up to three pages we need to check -- the page, and the
|
* There are up to three pages we need to check -- the page, and the
|
||||||
|
@ -1016,38 +1029,7 @@ __bam_relink_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
* the current page is the result of a split and is being recovered
|
* the current page is the result of a split and is being recovered
|
||||||
* elsewhere, so all we need do is recover the next page.
|
* elsewhere, so all we need do is recover the next page.
|
||||||
*/
|
*/
|
||||||
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
if ((ret = __memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
|
||||||
if (ret != DB_PAGE_NOTFOUND
|
|
||||||
#ifndef HAVE_FTRUNCATE
|
|
||||||
|| DB_REDO(op)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
ret = __db_pgerr(file_dbp, argp->pgno, ret);
|
|
||||||
goto out;
|
|
||||||
} else
|
|
||||||
goto next2;
|
|
||||||
}
|
|
||||||
modified = 0;
|
|
||||||
|
|
||||||
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn);
|
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
|
||||||
/* Redo the relink. */
|
|
||||||
pagep->lsn = *lsnp;
|
|
||||||
modified = 1;
|
|
||||||
} else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
|
|
||||||
/* Undo the relink. */
|
|
||||||
pagep->next_pgno = argp->next;
|
|
||||||
pagep->prev_pgno = argp->prev;
|
|
||||||
|
|
||||||
pagep->lsn = argp->lsn;
|
|
||||||
modified = 1;
|
|
||||||
}
|
|
||||||
if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
|
|
||||||
goto out;
|
|
||||||
pagep = NULL;
|
|
||||||
|
|
||||||
next2: if ((ret = __memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
|
|
||||||
if (ret != DB_PAGE_NOTFOUND
|
if (ret != DB_PAGE_NOTFOUND
|
||||||
#ifndef HAVE_FTRUNCATE
|
#ifndef HAVE_FTRUNCATE
|
||||||
|| DB_REDO(op)
|
|| DB_REDO(op)
|
||||||
|
@ -1062,24 +1044,24 @@ next2: if ((ret = __memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
|
||||||
modified = 0;
|
modified = 0;
|
||||||
cmp_n = log_compare(lsnp, &LSN(pagep));
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
cmp_p = log_compare(&LSN(pagep), &argp->lsn_next);
|
cmp_p = log_compare(&LSN(pagep), &argp->lsn_next);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn_next);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn_next);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/* Redo the remove or undo the add. */
|
/* Redo the remove or replace. */
|
||||||
pagep->prev_pgno = argp->prev;
|
if (argp->new_pgno == PGNO_INVALID)
|
||||||
|
pagep->prev_pgno = argp->prev;
|
||||||
|
else
|
||||||
|
pagep->prev_pgno = argp->new_pgno;
|
||||||
|
|
||||||
|
pagep->lsn = *lsnp;
|
||||||
modified = 1;
|
modified = 1;
|
||||||
} else if (cmp_n == 0 && DB_UNDO(op)) {
|
} else if (cmp_n == 0 && DB_UNDO(op)) {
|
||||||
/* Undo the remove or redo the add. */
|
/* Undo the remove or replace. */
|
||||||
pagep->prev_pgno = argp->pgno;
|
pagep->prev_pgno = argp->pgno;
|
||||||
|
|
||||||
|
pagep->lsn = argp->lsn_next;
|
||||||
modified = 1;
|
modified = 1;
|
||||||
}
|
}
|
||||||
if (modified == 1) {
|
|
||||||
if (DB_UNDO(op))
|
|
||||||
pagep->lsn = argp->lsn_next;
|
|
||||||
else
|
|
||||||
pagep->lsn = *lsnp;
|
|
||||||
}
|
|
||||||
if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
|
if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
pagep = NULL;
|
pagep = NULL;
|
||||||
|
@ -1098,24 +1080,24 @@ prev: if ((ret = __memp_fget(mpf, &argp->prev, 0, &pagep)) != 0) {
|
||||||
|
|
||||||
modified = 0;
|
modified = 0;
|
||||||
cmp_p = log_compare(&LSN(pagep), &argp->lsn_prev);
|
cmp_p = log_compare(&LSN(pagep), &argp->lsn_prev);
|
||||||
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn_prev);
|
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn_prev);
|
||||||
if (cmp_p == 0 && DB_REDO(op)) {
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
/* Redo the relink. */
|
/* Redo the relink. */
|
||||||
pagep->next_pgno = argp->next;
|
if (argp->new_pgno == PGNO_INVALID)
|
||||||
|
pagep->next_pgno = argp->next;
|
||||||
|
else
|
||||||
|
pagep->next_pgno = argp->new_pgno;
|
||||||
|
|
||||||
|
pagep->lsn = *lsnp;
|
||||||
modified = 1;
|
modified = 1;
|
||||||
} else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
|
} else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
|
||||||
/* Undo the relink. */
|
/* Undo the relink. */
|
||||||
pagep->next_pgno = argp->pgno;
|
pagep->next_pgno = argp->pgno;
|
||||||
|
pagep->lsn = argp->lsn_prev;
|
||||||
|
|
||||||
modified = 1;
|
modified = 1;
|
||||||
}
|
}
|
||||||
if (modified == 1) {
|
|
||||||
if (DB_UNDO(op))
|
|
||||||
pagep->lsn = argp->lsn_prev;
|
|
||||||
else
|
|
||||||
pagep->lsn = *lsnp;
|
|
||||||
}
|
|
||||||
if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
|
if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
pagep = NULL;
|
pagep = NULL;
|
||||||
|
@ -1127,3 +1109,281 @@ out: if (pagep != NULL)
|
||||||
(void)__memp_fput(mpf, pagep, 0);
|
(void)__memp_fput(mpf, pagep, 0);
|
||||||
REC_CLOSE;
|
REC_CLOSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __bam_merge_recover --
|
||||||
|
* Recovery function for merge.
|
||||||
|
*
|
||||||
|
* PUBLIC: int __bam_merge_recover
|
||||||
|
* PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__bam_merge_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
|
DB_ENV *dbenv;
|
||||||
|
DBT *dbtp;
|
||||||
|
DB_LSN *lsnp;
|
||||||
|
db_recops op;
|
||||||
|
void *info;
|
||||||
|
{
|
||||||
|
__bam_merge_args *argp;
|
||||||
|
BKEYDATA *bk;
|
||||||
|
DB *file_dbp;
|
||||||
|
DBC *dbc;
|
||||||
|
DB_MPOOLFILE *mpf;
|
||||||
|
PAGE *pagep;
|
||||||
|
db_indx_t indx, *ninp, *pinp;
|
||||||
|
u_int32_t size;
|
||||||
|
u_int8_t *bp;
|
||||||
|
int cmp_n, cmp_p, i, modified, ret;
|
||||||
|
|
||||||
|
COMPQUIET(info, NULL);
|
||||||
|
|
||||||
|
REC_PRINT(__bam_merge_print);
|
||||||
|
REC_INTRO(__bam_merge_read, 1, 1);
|
||||||
|
|
||||||
|
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
|
||||||
|
if (ret != DB_PAGE_NOTFOUND
|
||||||
|
#ifndef HAVE_FTRUNCATE
|
||||||
|
|| DB_REDO(op)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
ret = __db_pgerr(file_dbp, argp->pgno, ret);
|
||||||
|
goto out;
|
||||||
|
} else
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
|
modified = 0;
|
||||||
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
|
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
||||||
|
CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
|
||||||
|
|
||||||
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
|
/*
|
||||||
|
* If the header is provided the page is empty, copy the
|
||||||
|
* needed data.
|
||||||
|
*/
|
||||||
|
DB_ASSERT(argp->hdr.size == 0 || NUM_ENT(pagep) == 0);
|
||||||
|
if (argp->hdr.size != 0) {
|
||||||
|
P_INIT(pagep, file_dbp->pgsize, pagep->pgno,
|
||||||
|
PREV_PGNO(argp->hdr.data),
|
||||||
|
NEXT_PGNO(argp->hdr.data),
|
||||||
|
LEVEL(argp->hdr.data), TYPE(argp->hdr.data));
|
||||||
|
}
|
||||||
|
if (TYPE(pagep) == P_OVERFLOW) {
|
||||||
|
OV_REF(pagep) = OV_REF(argp->hdr.data);
|
||||||
|
OV_LEN(pagep) = OV_LEN(argp->hdr.data);
|
||||||
|
bp = (u_int8_t *) pagep + P_OVERHEAD(file_dbp);
|
||||||
|
memcpy(bp, argp->data.data, argp->data.size);
|
||||||
|
} else {
|
||||||
|
/* Copy the data segment. */
|
||||||
|
bp = (u_int8_t *)pagep +
|
||||||
|
(db_indx_t)(HOFFSET(pagep) - argp->data.size);
|
||||||
|
memcpy(bp, argp->data.data, argp->data.size);
|
||||||
|
|
||||||
|
/* Copy index table offset past the current entries. */
|
||||||
|
pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep);
|
||||||
|
ninp = argp->ind.data;
|
||||||
|
for (i = 0;
|
||||||
|
i < (int)(argp->ind.size / sizeof(*ninp)); i++)
|
||||||
|
*pinp++ = *ninp++
|
||||||
|
- (file_dbp->pgsize - HOFFSET(pagep));
|
||||||
|
HOFFSET(pagep) -= argp->data.size;
|
||||||
|
NUM_ENT(pagep) += i;
|
||||||
|
}
|
||||||
|
pagep->lsn = *lsnp;
|
||||||
|
modified = 1;
|
||||||
|
} else if (cmp_n == 0 && !DB_REDO(op)) {
|
||||||
|
/*
|
||||||
|
* Since logging is logical at the page level
|
||||||
|
* we cannot just truncate the data space. Delete
|
||||||
|
* the proper number of items from the logical end
|
||||||
|
* of the page.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < (int)(argp->ind.size / sizeof(*ninp)); i++) {
|
||||||
|
indx = NUM_ENT(pagep) - 1;
|
||||||
|
if (P_INP(file_dbp, pagep)[indx] ==
|
||||||
|
P_INP(file_dbp, pagep)[indx - P_INDX]) {
|
||||||
|
NUM_ENT(pagep)--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (TYPE(pagep)) {
|
||||||
|
case P_LBTREE:
|
||||||
|
case P_LRECNO:
|
||||||
|
case P_LDUP:
|
||||||
|
bk = GET_BKEYDATA(file_dbp, pagep, indx);
|
||||||
|
size = BITEM_SIZE(bk);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_IBTREE:
|
||||||
|
size = BINTERNAL_SIZE(
|
||||||
|
GET_BINTERNAL(file_dbp, pagep, indx)->len);
|
||||||
|
break;
|
||||||
|
case P_IRECNO:
|
||||||
|
size = RINTERNAL_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = __db_pgfmt(dbenv, PGNO(pagep));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if ((ret =
|
||||||
|
__db_ditem(dbc, pagep, indx, size)) != 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (argp->ind.size == 0)
|
||||||
|
HOFFSET(pagep) = file_dbp->pgsize;
|
||||||
|
pagep->lsn = argp->lsn;
|
||||||
|
modified = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
next: if ((ret = __memp_fget(mpf, &argp->npgno, 0, &pagep)) != 0) {
|
||||||
|
if (ret != DB_PAGE_NOTFOUND
|
||||||
|
#ifndef HAVE_FTRUNCATE
|
||||||
|
|| DB_REDO(op)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
ret = __db_pgerr(file_dbp, argp->pgno, ret);
|
||||||
|
goto out;
|
||||||
|
} else
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
modified = 0;
|
||||||
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
|
cmp_p = log_compare(&LSN(pagep), &argp->nlsn);
|
||||||
|
CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->nlsn);
|
||||||
|
|
||||||
|
if (cmp_p == 0 && DB_REDO(op)) {
|
||||||
|
/* Need to truncate the page. */
|
||||||
|
HOFFSET(pagep) = file_dbp->pgsize;
|
||||||
|
NUM_ENT(pagep) = 0;
|
||||||
|
pagep->lsn = *lsnp;
|
||||||
|
modified = 1;
|
||||||
|
} else if (cmp_n == 0 && !DB_REDO(op)) {
|
||||||
|
/* Need to put the data back on the page. */
|
||||||
|
if (TYPE(pagep) == P_OVERFLOW) {
|
||||||
|
OV_REF(pagep) = OV_REF(argp->hdr.data);
|
||||||
|
OV_LEN(pagep) = OV_LEN(argp->hdr.data);
|
||||||
|
bp = (u_int8_t *) pagep + P_OVERHEAD(file_dbp);
|
||||||
|
memcpy(bp, argp->data.data, argp->data.size);
|
||||||
|
} else {
|
||||||
|
bp = (u_int8_t *)pagep +
|
||||||
|
(db_indx_t)(HOFFSET(pagep) - argp->data.size);
|
||||||
|
memcpy(bp, argp->data.data, argp->data.size);
|
||||||
|
|
||||||
|
/* Copy index table. */
|
||||||
|
pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep);
|
||||||
|
ninp = argp->ind.data;
|
||||||
|
for (i = 0;
|
||||||
|
i < (int)(argp->ind.size / sizeof(*ninp)); i++)
|
||||||
|
*pinp++ = *ninp++;
|
||||||
|
HOFFSET(pagep) -= argp->data.size;
|
||||||
|
NUM_ENT(pagep) = i;
|
||||||
|
}
|
||||||
|
pagep->lsn = argp->nlsn;
|
||||||
|
modified = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
|
||||||
|
goto out;
|
||||||
|
done:
|
||||||
|
*lsnp = argp->prev_lsn;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out: REC_CLOSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __bam_pgno_recover --
|
||||||
|
* Recovery function for page number replacment.
|
||||||
|
*
|
||||||
|
* PUBLIC: int __bam_pgno_recover
|
||||||
|
* PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__bam_pgno_recover(dbenv, dbtp, lsnp, op, info)
|
||||||
|
DB_ENV *dbenv;
|
||||||
|
DBT *dbtp;
|
||||||
|
DB_LSN *lsnp;
|
||||||
|
db_recops op;
|
||||||
|
void *info;
|
||||||
|
{
|
||||||
|
BINTERNAL *bi;
|
||||||
|
__bam_pgno_args *argp;
|
||||||
|
DB *file_dbp;
|
||||||
|
DBC *dbc;
|
||||||
|
DB_MPOOLFILE *mpf;
|
||||||
|
PAGE *pagep, *npagep;
|
||||||
|
db_pgno_t *pgnop;
|
||||||
|
int cmp_n, cmp_p, modified, ret;
|
||||||
|
|
||||||
|
COMPQUIET(info, NULL);
|
||||||
|
|
||||||
|
REC_PRINT(__bam_pgno_print);
|
||||||
|
REC_INTRO(__bam_pgno_read, 1, 0);
|
||||||
|
|
||||||
|
REC_FGET(mpf, argp->pgno, &pagep, done);
|
||||||
|
|
||||||
|
modified = 0;
|
||||||
|
cmp_n = log_compare(lsnp, &LSN(pagep));
|
||||||
|
cmp_p = log_compare(&LSN(pagep), &argp->lsn);
|
||||||
|
CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
|
||||||
|
|
||||||
|
if ((cmp_p == 0 && DB_REDO(op)) || (cmp_n == 0 && !DB_REDO(op))) {
|
||||||
|
switch (TYPE(pagep)) {
|
||||||
|
case P_IBTREE:
|
||||||
|
/*
|
||||||
|
* An internal record can have both a overflow
|
||||||
|
* and child pointer. Fetch the page to see
|
||||||
|
* which it is.
|
||||||
|
*/
|
||||||
|
bi = GET_BINTERNAL(file_dbp, pagep, argp->indx);
|
||||||
|
if (B_TYPE(bi->type) == B_OVERFLOW) {
|
||||||
|
REC_FGET(mpf, argp->npgno, &npagep, out);
|
||||||
|
|
||||||
|
if (TYPE(npagep) == P_OVERFLOW)
|
||||||
|
pgnop =
|
||||||
|
&((BOVERFLOW *)(bi->data))->pgno;
|
||||||
|
else
|
||||||
|
pgnop = &bi->pgno;
|
||||||
|
if ((ret = __memp_fput(mpf, npagep, 0)) != 0)
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pgnop = &bi->pgno;
|
||||||
|
break;
|
||||||
|
case P_IRECNO:
|
||||||
|
pgnop =
|
||||||
|
&GET_RINTERNAL(file_dbp, pagep, argp->indx)->pgno;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pgnop =
|
||||||
|
&GET_BOVERFLOW(file_dbp, pagep, argp->indx)->pgno;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DB_REDO(op)) {
|
||||||
|
/* Need to redo update described. */
|
||||||
|
*pgnop = argp->npgno;
|
||||||
|
pagep->lsn = *lsnp;
|
||||||
|
modified = 1;
|
||||||
|
} else {
|
||||||
|
*pgnop = argp->opgno;
|
||||||
|
pagep->lsn = argp->lsn;
|
||||||
|
modified = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
done:
|
||||||
|
*lsnp = argp->prev_lsn;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out: REC_CLOSE;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998-2004
|
* Copyright (c) 1998-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_reclaim.c,v 11.15 2004/01/28 03:35:49 bostic Exp $
|
* $Id: bt_reclaim.c,v 12.2 2005/06/16 20:20:19 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -69,7 +69,8 @@ __bam_truncate(dbc, countp)
|
||||||
ret = __bam_traverse(dbc,
|
ret = __bam_traverse(dbc,
|
||||||
DB_LOCK_WRITE, dbc->internal->root, __db_truncate_callback, &trunc);
|
DB_LOCK_WRITE, dbc->internal->root, __db_truncate_callback, &trunc);
|
||||||
|
|
||||||
*countp = trunc.count;
|
if (countp != NULL)
|
||||||
|
*countp = trunc.count;
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1997-2004
|
* Copyright (c) 1997-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_recno.c,v 11.117 2004/03/28 17:01:01 bostic Exp $
|
* $Id: bt_recno.c,v 12.6 2005/08/08 14:27:59 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -203,7 +203,6 @@ __ram_c_del(dbc)
|
||||||
DB *dbp;
|
DB *dbp;
|
||||||
DB_LSN lsn;
|
DB_LSN lsn;
|
||||||
DBT hdr, data;
|
DBT hdr, data;
|
||||||
EPG *epg;
|
|
||||||
int exact, ret, stack, t_ret;
|
int exact, ret, stack, t_ret;
|
||||||
|
|
||||||
dbp = dbc->dbp;
|
dbp = dbc->dbp;
|
||||||
|
@ -280,21 +279,11 @@ __ram_c_del(dbc)
|
||||||
* are closed, and then clean it up.
|
* are closed, and then clean it up.
|
||||||
*/
|
*/
|
||||||
if (NUM_ENT(cp->page) == 0 && PGNO(cp->page) != cp->root) {
|
if (NUM_ENT(cp->page) == 0 && PGNO(cp->page) != cp->root) {
|
||||||
/*
|
|
||||||
* We already have a locked stack of pages. However,
|
|
||||||
* there are likely entries in the stack that aren't
|
|
||||||
* going to be emptied by removing the single reference
|
|
||||||
* to the emptied page (or one of its parents).
|
|
||||||
*/
|
|
||||||
for (epg = cp->csp; epg >= cp->sp; --epg)
|
|
||||||
if (NUM_ENT(epg->page) > 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to delete a single item out of the last page
|
* We want to delete a single item out of the last page
|
||||||
* that we're not deleting.
|
* that we're not deleting.
|
||||||
*/
|
*/
|
||||||
ret = __bam_dpages(dbc, epg);
|
ret = __bam_dpages(dbc, 0, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Regardless of the return from __bam_dpages, it will
|
* Regardless of the return from __bam_dpages, it will
|
||||||
|
@ -764,7 +753,7 @@ __ram_ca(dbc_arg, op)
|
||||||
*/
|
*/
|
||||||
DB_ASSERT(F_ISSET(cp_arg, C_RENUMBER));
|
DB_ASSERT(F_ISSET(cp_arg, C_RENUMBER));
|
||||||
|
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
|
||||||
/*
|
/*
|
||||||
* Adjust the cursors. See the comment in __bam_ca_delete().
|
* Adjust the cursors. See the comment in __bam_ca_delete().
|
||||||
*/
|
*/
|
||||||
|
@ -780,7 +769,7 @@ __ram_ca(dbc_arg, op)
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
cp = (BTREE_CURSOR *)dbc->internal;
|
cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
|
@ -789,7 +778,7 @@ __ram_ca(dbc_arg, op)
|
||||||
order <= cp->order)
|
order <= cp->order)
|
||||||
order = cp->order + 1;
|
order = cp->order + 1;
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
order = INVALID_ORDER;
|
order = INVALID_ORDER;
|
||||||
|
@ -798,7 +787,7 @@ __ram_ca(dbc_arg, op)
|
||||||
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
|
||||||
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
|
||||||
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
|
||||||
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
|
MUTEX_LOCK(dbenv, dbp->mutex);
|
||||||
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
|
||||||
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
|
||||||
cp = (BTREE_CURSOR *)dbc->internal;
|
cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
|
@ -868,9 +857,9 @@ iafter: if (!adjusted && C_LESSTHAN(cp_arg, cp)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbp->dbenv, dbp->mutexp);
|
MUTEX_UNLOCK(dbp->dbenv, dbp->mutex);
|
||||||
}
|
}
|
||||||
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
|
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
|
||||||
|
|
||||||
return (found);
|
return (found);
|
||||||
}
|
}
|
||||||
|
@ -1037,6 +1026,18 @@ __ram_writeback(dbp)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We step through the records, writing each one out. Use the record
|
||||||
|
* number and the dbp->get() function, instead of a cursor, so we find
|
||||||
|
* and write out "deleted" or non-existent records. The DB handle may
|
||||||
|
* be threaded, so allocate memory as we go.
|
||||||
|
*/
|
||||||
|
memset(&key, 0, sizeof(key));
|
||||||
|
key.size = sizeof(db_recno_t);
|
||||||
|
key.data = &keyno;
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
F_SET(&data, DB_DBT_REALLOC);
|
||||||
|
|
||||||
/* Allocate a cursor. */
|
/* Allocate a cursor. */
|
||||||
if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0)
|
if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0)
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -1064,7 +1065,7 @@ __ram_writeback(dbp)
|
||||||
*/
|
*/
|
||||||
if ((ret =
|
if ((ret =
|
||||||
__ram_update(dbc, DB_MAX_RECORDS, 0)) != 0 && ret != DB_NOTFOUND)
|
__ram_update(dbc, DB_MAX_RECORDS, 0)) != 0 && ret != DB_NOTFOUND)
|
||||||
return (ret);
|
goto err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close any existing file handle and re-open the file, truncating it.
|
* Close any existing file handle and re-open the file, truncating it.
|
||||||
|
@ -1082,18 +1083,6 @@ __ram_writeback(dbp)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* We step through the records, writing each one out. Use the record
|
|
||||||
* number and the dbp->get() function, instead of a cursor, so we find
|
|
||||||
* and write out "deleted" or non-existent records. The DB handle may
|
|
||||||
* be threaded, so allocate memory as we go.
|
|
||||||
*/
|
|
||||||
memset(&key, 0, sizeof(key));
|
|
||||||
key.size = sizeof(db_recno_t);
|
|
||||||
key.data = &keyno;
|
|
||||||
memset(&data, 0, sizeof(data));
|
|
||||||
F_SET(&data, DB_DBT_REALLOC);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We'll need the delimiter if we're doing variable-length records,
|
* We'll need the delimiter if we're doing variable-length records,
|
||||||
* and the pad character if we're doing fixed-length records.
|
* and the pad character if we're doing fixed-length records.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: bt_rsearch.c,v 11.40 2004/07/23 17:21:09 bostic Exp $
|
* $Id: bt_rsearch.c,v 12.5 2005/08/08 03:37:05 ubell Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -100,44 +100,14 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
|
||||||
*
|
*
|
||||||
* Retrieve the root page.
|
* Retrieve the root page.
|
||||||
*/
|
*/
|
||||||
pg = cp->root;
|
|
||||||
stack = LF_ISSET(S_STACK) ? 1 : 0;
|
|
||||||
lock_mode = stack ? DB_LOCK_WRITE : DB_LOCK_READ;
|
|
||||||
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
|
|
||||||
return (ret);
|
|
||||||
if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
|
|
||||||
/* Did not read it, so we can release the lock */
|
|
||||||
(void)__LPUT(dbc, lock);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if ((ret = __bam_get_root(dbc, cp->root, stop, flags, &stack)) != 0)
|
||||||
* Decide if we need to save this page; if we do, write lock it.
|
return (ret);
|
||||||
* We deliberately don't lock-couple on this call. If the tree
|
lock_mode = cp->csp->lock_mode;
|
||||||
* is tiny, i.e., one page, and two threads are busily updating
|
lock = cp->csp->lock;
|
||||||
* the root page, we're almost guaranteed deadlocks galore, as
|
h = cp->csp->page;
|
||||||
* each one gets a read lock and then blocks the other's attempt
|
|
||||||
* for a write lock.
|
|
||||||
*/
|
|
||||||
if (!stack &&
|
|
||||||
((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
|
|
||||||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
|
|
||||||
ret = __memp_fput(mpf, h, 0);
|
|
||||||
if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
|
|
||||||
ret = t_ret;
|
|
||||||
if (ret != 0)
|
|
||||||
return (ret);
|
|
||||||
lock_mode = DB_LOCK_WRITE;
|
|
||||||
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
|
|
||||||
return (ret);
|
|
||||||
if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
|
|
||||||
/* Did not read it, so we can release the lock */
|
|
||||||
(void)__LPUT(dbc, lock);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
stack = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
BT_STK_CLR(cp);
|
||||||
/*
|
/*
|
||||||
* If appending to the tree, set the record number now -- we have the
|
* If appending to the tree, set the record number now -- we have the
|
||||||
* root page locked.
|
* root page locked.
|
||||||
|
@ -260,15 +230,15 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
|
||||||
}
|
}
|
||||||
--indx;
|
--indx;
|
||||||
|
|
||||||
|
/* Return if this is the lowest page wanted. */
|
||||||
|
if (stop == LEVEL(h)) {
|
||||||
|
BT_STK_ENTER(dbp->dbenv,
|
||||||
|
cp, h, indx, lock, lock_mode, ret);
|
||||||
|
if (ret != 0)
|
||||||
|
goto err;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
if (stack) {
|
if (stack) {
|
||||||
/* Return if this is the lowest page wanted. */
|
|
||||||
if (LF_ISSET(S_PARENT) && stop == h->level) {
|
|
||||||
BT_STK_ENTER(dbp->dbenv,
|
|
||||||
cp, h, indx, lock, lock_mode, ret);
|
|
||||||
if (ret != 0)
|
|
||||||
goto err;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
BT_STK_PUSH(dbp->dbenv,
|
BT_STK_PUSH(dbp->dbenv,
|
||||||
cp, h, indx, lock, lock_mode, ret);
|
cp, h, indx, lock, lock_mode, ret);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -286,8 +256,8 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
|
||||||
* never unlock it.
|
* never unlock it.
|
||||||
*/
|
*/
|
||||||
if ((LF_ISSET(S_PARENT) &&
|
if ((LF_ISSET(S_PARENT) &&
|
||||||
(u_int8_t)(stop + 1) >= (u_int8_t)(h->level - 1)) ||
|
(u_int8_t)(stop + 1) >= (u_int8_t)(LEVEL(h) - 1)) ||
|
||||||
(h->level - 1) == LEAFLEVEL)
|
(LEVEL(h) - 1) == LEAFLEVEL)
|
||||||
stack = 1;
|
stack = 1;
|
||||||
|
|
||||||
if ((ret = __memp_fput(mpf, h, 0)) != 0)
|
if ((ret = __memp_fput(mpf, h, 0)) != 0)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: bt_search.c,v 11.50 2004/07/23 17:21:09 bostic Exp $
|
* $Id: bt_search.c,v 12.17 2005/11/10 21:17:13 ubell Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -57,6 +57,102 @@
|
||||||
#include "dbinc/lock.h"
|
#include "dbinc/lock.h"
|
||||||
#include "dbinc/mp.h"
|
#include "dbinc/mp.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __bam_get_root --
|
||||||
|
* Fetch the root of a tree and see if we want to keep
|
||||||
|
* it in the stack.
|
||||||
|
*
|
||||||
|
* PUBLIC: int __bam_get_root __P((DBC *, db_pgno_t, int, u_int32_t, int *));
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__bam_get_root(dbc, pg, slevel, flags, stack)
|
||||||
|
DBC *dbc;
|
||||||
|
db_pgno_t pg;
|
||||||
|
int slevel;
|
||||||
|
u_int32_t flags;
|
||||||
|
int *stack;
|
||||||
|
{
|
||||||
|
BTREE_CURSOR *cp;
|
||||||
|
DB *dbp;
|
||||||
|
DB_LOCK lock;
|
||||||
|
DB_MPOOLFILE *mpf;
|
||||||
|
PAGE *h;
|
||||||
|
db_lockmode_t lock_mode;
|
||||||
|
int ret, t_ret;
|
||||||
|
|
||||||
|
dbp = dbc->dbp;
|
||||||
|
mpf = dbp->mpf;
|
||||||
|
cp = (BTREE_CURSOR *)dbc->internal;
|
||||||
|
/*
|
||||||
|
* If write-locking pages, we need to know whether or not to acquire a
|
||||||
|
* write lock on a page before getting it. This depends on how deep it
|
||||||
|
* is in tree, which we don't know until we acquire the root page. So,
|
||||||
|
* if we need to lock the root page we may have to upgrade it later,
|
||||||
|
* because we won't get the correct lock initially.
|
||||||
|
*
|
||||||
|
* Retrieve the root page.
|
||||||
|
*/
|
||||||
|
try_again:
|
||||||
|
*stack = LF_ISSET(S_STACK) &&
|
||||||
|
(dbc->dbtype == DB_RECNO || F_ISSET(cp, C_RECNUM));
|
||||||
|
lock_mode = DB_LOCK_READ;
|
||||||
|
if (*stack ||
|
||||||
|
LF_ISSET(S_DEL) || (LF_ISSET(S_NEXT) && LF_ISSET(S_WRITE)))
|
||||||
|
lock_mode = DB_LOCK_WRITE;
|
||||||
|
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
|
||||||
|
return (ret);
|
||||||
|
if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
|
||||||
|
/* Did not read it, so we can release the lock */
|
||||||
|
(void)__LPUT(dbc, lock);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decide if we need to save this page; if we do, write lock it.
|
||||||
|
* We deliberately don't lock-couple on this call. If the tree
|
||||||
|
* is tiny, i.e., one page, and two threads are busily updating
|
||||||
|
* the root page, we're almost guaranteed deadlocks galore, as
|
||||||
|
* each one gets a read lock and then blocks the other's attempt
|
||||||
|
* for a write lock.
|
||||||
|
*/
|
||||||
|
if (!*stack &&
|
||||||
|
((LF_ISSET(S_PARENT) && (u_int8_t)(slevel + 1) >= LEVEL(h)) ||
|
||||||
|
(LF_ISSET(S_WRITE) && LEVEL(h) == LEAFLEVEL) ||
|
||||||
|
(LF_ISSET(S_START) && slevel == LEVEL(h)))) {
|
||||||
|
if (!STD_LOCKING(dbc))
|
||||||
|
goto no_relock;
|
||||||
|
ret = __memp_fput(mpf, h, 0);
|
||||||
|
if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
if (ret != 0)
|
||||||
|
return (ret);
|
||||||
|
lock_mode = DB_LOCK_WRITE;
|
||||||
|
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
|
||||||
|
return (ret);
|
||||||
|
if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
|
||||||
|
/* Did not read it, so we can release the lock */
|
||||||
|
(void)__LPUT(dbc, lock);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
if (!((LF_ISSET(S_PARENT) &&
|
||||||
|
(u_int8_t)(slevel + 1) >= LEVEL(h)) ||
|
||||||
|
(LF_ISSET(S_WRITE) && LEVEL(h) == LEAFLEVEL) ||
|
||||||
|
(LF_ISSET(S_START) && slevel == LEVEL(h)))) {
|
||||||
|
/* Someone else split the root, start over. */
|
||||||
|
ret = __memp_fput(mpf, h, 0);
|
||||||
|
if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
if (ret != 0)
|
||||||
|
return (ret);
|
||||||
|
goto try_again;
|
||||||
|
}
|
||||||
|
no_relock: *stack = 1;
|
||||||
|
}
|
||||||
|
BT_STK_ENTER(dbp->dbenv, cp, h, 0, lock, lock_mode, ret);
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __bam_search --
|
* __bam_search --
|
||||||
* Search a btree for a key.
|
* Search a btree for a key.
|
||||||
|
@ -65,12 +161,12 @@
|
||||||
* PUBLIC: const DBT *, u_int32_t, int, db_recno_t *, int *));
|
* PUBLIC: const DBT *, u_int32_t, int, db_recno_t *, int *));
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
__bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
|
__bam_search(dbc, root_pgno, key, flags, slevel, recnop, exactp)
|
||||||
DBC *dbc;
|
DBC *dbc;
|
||||||
db_pgno_t root_pgno;
|
db_pgno_t root_pgno;
|
||||||
const DBT *key;
|
const DBT *key;
|
||||||
u_int32_t flags;
|
u_int32_t flags;
|
||||||
int stop, *exactp;
|
int slevel, *exactp;
|
||||||
db_recno_t *recnop;
|
db_recno_t *recnop;
|
||||||
{
|
{
|
||||||
BTREE *t;
|
BTREE *t;
|
||||||
|
@ -102,64 +198,17 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
|
||||||
* deleted items, and if we are locking pairs of pages. In addition,
|
* deleted items, and if we are locking pairs of pages. In addition,
|
||||||
* if we're modifying record numbers, we have to lock the entire tree
|
* if we're modifying record numbers, we have to lock the entire tree
|
||||||
* regardless. See btree.h for more details.
|
* regardless. See btree.h for more details.
|
||||||
*
|
|
||||||
* If write-locking pages, we need to know whether or not to acquire a
|
|
||||||
* write lock on a page before getting it. This depends on how deep it
|
|
||||||
* is in tree, which we don't know until we acquire the root page. So,
|
|
||||||
* if we need to lock the root page we may have to upgrade it later,
|
|
||||||
* because we won't get the correct lock initially.
|
|
||||||
*
|
|
||||||
* Retrieve the root page.
|
|
||||||
*/
|
*/
|
||||||
try_again:
|
|
||||||
pg = root_pgno == PGNO_INVALID ? cp->root : root_pgno;
|
|
||||||
stack = LF_ISSET(S_STACK) && F_ISSET(cp, C_RECNUM);
|
|
||||||
lock_mode = stack ? DB_LOCK_WRITE : DB_LOCK_READ;
|
|
||||||
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
|
|
||||||
return (ret);
|
|
||||||
if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
|
|
||||||
/* Did not read it, so we can release the lock */
|
|
||||||
(void)__LPUT(dbc, lock);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if (root_pgno == PGNO_INVALID)
|
||||||
* Decide if we need to save this page; if we do, write lock it.
|
root_pgno = cp->root;
|
||||||
* We deliberately don't lock-couple on this call. If the tree
|
if ((ret = __bam_get_root(dbc, root_pgno, slevel, flags, &stack)) != 0)
|
||||||
* is tiny, i.e., one page, and two threads are busily updating
|
return (ret);
|
||||||
* the root page, we're almost guaranteed deadlocks galore, as
|
lock_mode = cp->csp->lock_mode;
|
||||||
* each one gets a read lock and then blocks the other's attempt
|
lock = cp->csp->lock;
|
||||||
* for a write lock.
|
h = cp->csp->page;
|
||||||
*/
|
|
||||||
if (!stack &&
|
BT_STK_CLR(cp);
|
||||||
((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
|
|
||||||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
|
|
||||||
ret = __memp_fput(mpf, h, 0);
|
|
||||||
if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
|
|
||||||
ret = t_ret;
|
|
||||||
if (ret != 0)
|
|
||||||
return (ret);
|
|
||||||
lock_mode = DB_LOCK_WRITE;
|
|
||||||
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
|
|
||||||
return (ret);
|
|
||||||
if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
|
|
||||||
/* Did not read it, so we can release the lock */
|
|
||||||
(void)__LPUT(dbc, lock);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
if (!((LF_ISSET(S_PARENT) &&
|
|
||||||
(u_int8_t)(stop + 1) >= h->level) ||
|
|
||||||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
|
|
||||||
/* Someone else split the root, start over. */
|
|
||||||
ret = __memp_fput(mpf, h, 0);
|
|
||||||
if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
|
|
||||||
ret = t_ret;
|
|
||||||
if (ret != 0)
|
|
||||||
return (ret);
|
|
||||||
goto try_again;
|
|
||||||
}
|
|
||||||
stack = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Choose a comparison function. */
|
/* Choose a comparison function. */
|
||||||
func = F_ISSET(dbc, DBC_OPD) ?
|
func = F_ISSET(dbc, DBC_OPD) ?
|
||||||
|
@ -168,6 +217,23 @@ try_again:
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
inp = P_INP(dbp, h);
|
inp = P_INP(dbp, h);
|
||||||
|
adjust = TYPE(h) == P_LBTREE ? P_INDX : O_INDX;
|
||||||
|
if (LF_ISSET(S_MIN | S_MAX)) {
|
||||||
|
if (LF_ISSET(S_MIN) || NUM_ENT(h) == 0)
|
||||||
|
indx = 0;
|
||||||
|
else if (TYPE(h) == P_LBTREE)
|
||||||
|
indx = NUM_ENT(h) - 2;
|
||||||
|
else
|
||||||
|
indx = NUM_ENT(h) - 1;
|
||||||
|
|
||||||
|
if (LEVEL(h) == LEAFLEVEL ||
|
||||||
|
(!LF_ISSET(S_START) && LEVEL(h) == slevel)) {
|
||||||
|
if (LF_ISSET(S_NEXT))
|
||||||
|
goto get_next;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Do a binary search on the current page. If we're searching
|
* Do a binary search on the current page. If we're searching
|
||||||
* a Btree leaf page, we have to walk the indices in groups of
|
* a Btree leaf page, we have to walk the indices in groups of
|
||||||
|
@ -175,7 +241,6 @@ try_again:
|
||||||
* page, they're an index per page item. If we find an exact
|
* page, they're an index per page item. If we find an exact
|
||||||
* match on a leaf page, we're done.
|
* match on a leaf page, we're done.
|
||||||
*/
|
*/
|
||||||
adjust = TYPE(h) == P_LBTREE ? P_INDX : O_INDX;
|
|
||||||
for (base = 0,
|
for (base = 0,
|
||||||
lim = NUM_ENT(h) / (db_indx_t)adjust; lim != 0; lim >>= 1) {
|
lim = NUM_ENT(h) / (db_indx_t)adjust; lim != 0; lim >>= 1) {
|
||||||
indx = base + ((lim >> 1) * adjust);
|
indx = base + ((lim >> 1) * adjust);
|
||||||
|
@ -183,8 +248,13 @@ try_again:
|
||||||
__bam_cmp(dbp, key, h, indx, func, &cmp)) != 0)
|
__bam_cmp(dbp, key, h, indx, func, &cmp)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
if (cmp == 0) {
|
if (cmp == 0) {
|
||||||
if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP)
|
if (LEVEL(h) == LEAFLEVEL ||
|
||||||
|
(!LF_ISSET(S_START) &&
|
||||||
|
LEVEL(h) == slevel)) {
|
||||||
|
if (LF_ISSET(S_NEXT))
|
||||||
|
goto get_next;
|
||||||
goto found;
|
goto found;
|
||||||
|
}
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
|
@ -197,10 +267,12 @@ try_again:
|
||||||
* No match found. Base is the smallest index greater than
|
* No match found. Base is the smallest index greater than
|
||||||
* key and may be zero or a last + O_INDX index.
|
* key and may be zero or a last + O_INDX index.
|
||||||
*
|
*
|
||||||
* If it's a leaf page, return base as the "found" value.
|
* If it's a leaf page or the stopping point,
|
||||||
|
* return base as the "found" value.
|
||||||
* Delete only deletes exact matches.
|
* Delete only deletes exact matches.
|
||||||
*/
|
*/
|
||||||
if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP) {
|
if (LEVEL(h) == LEAFLEVEL ||
|
||||||
|
(!LF_ISSET(S_START) && LEVEL(h) == slevel)) {
|
||||||
*exactp = 0;
|
*exactp = 0;
|
||||||
|
|
||||||
if (LF_ISSET(S_EXACT)) {
|
if (LF_ISSET(S_EXACT)) {
|
||||||
|
@ -218,6 +290,43 @@ try_again:
|
||||||
ret = t_ret;
|
ret = t_ret;
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
if (LF_ISSET(S_NEXT)) {
|
||||||
|
get_next: /*
|
||||||
|
* The caller could have asked for a NEXT
|
||||||
|
* at the root if the tree recently collapsed.
|
||||||
|
*/
|
||||||
|
if (PGNO(h) == root_pgno) {
|
||||||
|
ret = DB_NOTFOUND;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Save the root of the subtree
|
||||||
|
* and drop the rest of the subtree
|
||||||
|
* and search down again starting at
|
||||||
|
* the next child.
|
||||||
|
*/
|
||||||
|
if ((ret = __LPUT(dbc, lock)) != 0)
|
||||||
|
goto err;
|
||||||
|
if ((ret = __memp_fput(mpf, h, 0)) != 0)
|
||||||
|
goto err;
|
||||||
|
h = NULL;
|
||||||
|
LF_SET(S_MIN);
|
||||||
|
LF_CLR(S_NEXT);
|
||||||
|
indx = cp->sp->indx + 1;
|
||||||
|
if (indx == NUM_ENT(cp->sp->page)) {
|
||||||
|
ret = DB_NOTFOUND;
|
||||||
|
cp->csp++;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
h = cp->sp->page;
|
||||||
|
cp->sp->page = NULL;
|
||||||
|
lock = cp->sp->lock;
|
||||||
|
LOCK_INIT(cp->sp->lock);
|
||||||
|
if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0)
|
||||||
|
goto err;
|
||||||
|
stack = 1;
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* !!!
|
* !!!
|
||||||
|
@ -227,6 +336,8 @@ try_again:
|
||||||
* to find an undeleted record. This is handled by the
|
* to find an undeleted record. This is handled by the
|
||||||
* calling routine.
|
* calling routine.
|
||||||
*/
|
*/
|
||||||
|
if (LF_ISSET(S_DEL) && cp->csp == cp->sp)
|
||||||
|
cp->csp++;
|
||||||
BT_STK_ENTER(dbp->dbenv,
|
BT_STK_ENTER(dbp->dbenv,
|
||||||
cp, h, base, lock, lock_mode, ret);
|
cp, h, base, lock, lock_mode, ret);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -252,8 +363,12 @@ next: if (recnop != NULL)
|
||||||
|
|
||||||
pg = GET_BINTERNAL(dbp, h, indx)->pgno;
|
pg = GET_BINTERNAL(dbp, h, indx)->pgno;
|
||||||
|
|
||||||
|
/* See if we are at the level to start stacking. */
|
||||||
|
if (LF_ISSET(S_START) && slevel == LEVEL(h))
|
||||||
|
stack = 1;
|
||||||
|
|
||||||
if (LF_ISSET(S_STK_ONLY)) {
|
if (LF_ISSET(S_STK_ONLY)) {
|
||||||
if (stop == h->level) {
|
if (slevel == LEVEL(h)) {
|
||||||
BT_STK_NUM(dbp->dbenv, cp, h, indx, ret);
|
BT_STK_NUM(dbp->dbenv, cp, h, indx, ret);
|
||||||
if ((t_ret =
|
if ((t_ret =
|
||||||
__LPUT(dbc, lock)) != 0 && ret == 0)
|
__LPUT(dbc, lock)) != 0 && ret == 0)
|
||||||
|
@ -278,13 +393,24 @@ next: if (recnop != NULL)
|
||||||
}
|
}
|
||||||
} else if (stack) {
|
} else if (stack) {
|
||||||
/* Return if this is the lowest page wanted. */
|
/* Return if this is the lowest page wanted. */
|
||||||
if (LF_ISSET(S_PARENT) && stop == h->level) {
|
if (LF_ISSET(S_PARENT) && slevel == LEVEL(h)) {
|
||||||
BT_STK_ENTER(dbp->dbenv,
|
BT_STK_ENTER(dbp->dbenv,
|
||||||
cp, h, indx, lock, lock_mode, ret);
|
cp, h, indx, lock, lock_mode, ret);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto err;
|
goto err;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
if (LF_ISSET(S_DEL) && NUM_ENT(h) > 1) {
|
||||||
|
/*
|
||||||
|
* There was a page with a singleton pointer
|
||||||
|
* to a non-empty subtree.
|
||||||
|
*/
|
||||||
|
cp->csp--;
|
||||||
|
if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0)
|
||||||
|
goto err;
|
||||||
|
stack = 0;
|
||||||
|
goto do_del;
|
||||||
|
}
|
||||||
BT_STK_PUSH(dbp->dbenv,
|
BT_STK_PUSH(dbp->dbenv,
|
||||||
cp, h, indx, lock, lock_mode, ret);
|
cp, h, indx, lock, lock_mode, ret);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -302,16 +428,69 @@ next: if (recnop != NULL)
|
||||||
* unlock it.
|
* unlock it.
|
||||||
*/
|
*/
|
||||||
if ((LF_ISSET(S_PARENT) &&
|
if ((LF_ISSET(S_PARENT) &&
|
||||||
(u_int8_t)(stop + 1) >= (u_int8_t)(h->level - 1)) ||
|
(u_int8_t)(slevel + 1) >= (LEVEL(h) - 1)) ||
|
||||||
(h->level - 1) == LEAFLEVEL)
|
(LEVEL(h) - 1) == LEAFLEVEL)
|
||||||
stack = 1;
|
stack = 1;
|
||||||
|
|
||||||
if ((ret = __memp_fput(mpf, h, 0)) != 0)
|
/*
|
||||||
goto err;
|
* Returning a subtree. See if we have hit the start
|
||||||
h = NULL;
|
* point if so save the parent and set stack.
|
||||||
|
* Otherwise free the parent and temporarily
|
||||||
|
* save this one.
|
||||||
|
* For S_DEL we need to find a page with 1 entry.
|
||||||
|
* For S_NEXT we want find the minimal subtree
|
||||||
|
* that contains the key and the next page.
|
||||||
|
* We save pages as long as we are at the right
|
||||||
|
* edge of the subtree. When we leave the right
|
||||||
|
* edge, then drop the subtree.
|
||||||
|
*/
|
||||||
|
if (!LF_ISSET(S_DEL | S_NEXT)) {
|
||||||
|
if ((ret = __memp_fput(mpf, h, 0)) != 0)
|
||||||
|
goto err;
|
||||||
|
goto lock_next;
|
||||||
|
}
|
||||||
|
|
||||||
lock_mode = stack &&
|
if ((LF_ISSET(S_DEL) && NUM_ENT(h) == 1)) {
|
||||||
LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ;
|
stack = 1;
|
||||||
|
LF_SET(S_WRITE);
|
||||||
|
/* Push the parent. */
|
||||||
|
cp->csp++;
|
||||||
|
/* Push this node. */
|
||||||
|
BT_STK_PUSH(dbp->dbenv, cp, h,
|
||||||
|
indx, lock, lock_mode, ret);
|
||||||
|
if (ret != 0)
|
||||||
|
goto err;
|
||||||
|
LOCK_INIT(lock);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* See if we want to save the tree so far.
|
||||||
|
* If we are looking for the next key,
|
||||||
|
* then we must save this node if we are
|
||||||
|
* at the end of the page. If not then
|
||||||
|
* discard anything we have saved so far.
|
||||||
|
* For delete only keep one node until
|
||||||
|
* we find a singleton.
|
||||||
|
*/
|
||||||
|
do_del: if (cp->csp->page != NULL) {
|
||||||
|
if (LF_ISSET(S_NEXT) &&
|
||||||
|
indx == NUM_ENT(h) - 1)
|
||||||
|
cp->csp++;
|
||||||
|
else if ((ret =
|
||||||
|
__bam_stkrel(dbc, STK_NOLOCK)) != 0)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
/* Save this node. */
|
||||||
|
BT_STK_ENTER(dbp->dbenv, cp,
|
||||||
|
h, indx, lock, lock_mode, ret);
|
||||||
|
if (ret != 0)
|
||||||
|
goto err;
|
||||||
|
LOCK_INIT(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock_next: h = NULL;
|
||||||
|
|
||||||
|
if (stack && LF_ISSET(S_WRITE))
|
||||||
|
lock_mode = DB_LOCK_WRITE;
|
||||||
if ((ret = __db_lget(dbc,
|
if ((ret = __db_lget(dbc,
|
||||||
LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) {
|
LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) {
|
||||||
/*
|
/*
|
||||||
|
@ -320,6 +499,8 @@ next: if (recnop != NULL)
|
||||||
* descending the tree holding read-locks.
|
* descending the tree holding read-locks.
|
||||||
*/
|
*/
|
||||||
(void)__LPUT(dbc, lock);
|
(void)__LPUT(dbc, lock);
|
||||||
|
if (LF_ISSET(S_DEL | S_NEXT))
|
||||||
|
cp->csp++;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,12 +521,12 @@ found: *exactp = 1;
|
||||||
* all duplicate sets that are not on overflow pages exist on a
|
* all duplicate sets that are not on overflow pages exist on a
|
||||||
* single leaf page.
|
* single leaf page.
|
||||||
*/
|
*/
|
||||||
if (TYPE(h) == P_LBTREE) {
|
if (TYPE(h) == P_LBTREE && NUM_ENT(h) > P_INDX) {
|
||||||
if (LF_ISSET(S_DUPLAST))
|
if (LF_ISSET(S_DUPLAST))
|
||||||
while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
|
while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
|
||||||
inp[indx] == inp[indx + P_INDX])
|
inp[indx] == inp[indx + P_INDX])
|
||||||
indx += P_INDX;
|
indx += P_INDX;
|
||||||
else
|
else if (LF_ISSET(S_DUPFIRST))
|
||||||
while (indx > 0 &&
|
while (indx > 0 &&
|
||||||
inp[indx] == inp[indx - P_INDX])
|
inp[indx] == inp[indx - P_INDX])
|
||||||
indx -= P_INDX;
|
indx -= P_INDX;
|
||||||
|
@ -406,8 +587,11 @@ found: *exactp = 1;
|
||||||
ret = t_ret;
|
ret = t_ret;
|
||||||
if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
|
if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
|
||||||
ret = t_ret;
|
ret = t_ret;
|
||||||
} else
|
} else {
|
||||||
|
if (LF_ISSET(S_DEL) && cp->csp == cp->sp)
|
||||||
|
cp->csp++;
|
||||||
BT_STK_ENTER(dbp->dbenv, cp, h, indx, lock, lock_mode, ret);
|
BT_STK_ENTER(dbp->dbenv, cp, h, indx, lock, lock_mode, ret);
|
||||||
|
}
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -471,6 +655,13 @@ __bam_stkrel(dbc, flags)
|
||||||
*/
|
*/
|
||||||
epg->page = NULL;
|
epg->page = NULL;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* We set this if we need to release our pins,
|
||||||
|
* but are not logically ready to have the pages
|
||||||
|
* visible.
|
||||||
|
*/
|
||||||
|
if (LF_ISSET(STK_PGONLY))
|
||||||
|
continue;
|
||||||
if (LF_ISSET(STK_NOLOCK)) {
|
if (LF_ISSET(STK_NOLOCK)) {
|
||||||
if ((t_ret = __LPUT(dbc, epg->lock)) != 0 && ret == 0)
|
if ((t_ret = __LPUT(dbc, epg->lock)) != 0 && ret == 0)
|
||||||
ret = t_ret;
|
ret = t_ret;
|
||||||
|
@ -480,7 +671,8 @@ __bam_stkrel(dbc, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the stack, all pages have been released. */
|
/* Clear the stack, all pages have been released. */
|
||||||
BT_STK_CLR(cp);
|
if (!LF_ISSET(STK_PGONLY))
|
||||||
|
BT_STK_CLR(cp);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: bt_split.c,v 11.66 2004/10/01 13:00:21 bostic Exp $
|
* $Id: bt_split.c,v 12.4 2005/06/16 20:20:22 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -56,7 +56,6 @@
|
||||||
|
|
||||||
static int __bam_broot __P((DBC *, PAGE *, PAGE *, PAGE *));
|
static int __bam_broot __P((DBC *, PAGE *, PAGE *, PAGE *));
|
||||||
static int __bam_page __P((DBC *, EPG *, EPG *));
|
static int __bam_page __P((DBC *, EPG *, EPG *));
|
||||||
static int __bam_pinsert __P((DBC *, EPG *, PAGE *, PAGE *, int));
|
|
||||||
static int __bam_psplit __P((DBC *, EPG *, PAGE *, PAGE *, db_indx_t *));
|
static int __bam_psplit __P((DBC *, EPG *, PAGE *, PAGE *, db_indx_t *));
|
||||||
static int __bam_root __P((DBC *, EPG *));
|
static int __bam_root __P((DBC *, EPG *));
|
||||||
static int __ram_root __P((DBC *, PAGE *, PAGE *, PAGE *));
|
static int __ram_root __P((DBC *, PAGE *, PAGE *, PAGE *));
|
||||||
|
@ -338,7 +337,7 @@ __bam_page(dbc, pp, cp)
|
||||||
* page can't hold the new keys, and has to be split in turn, in which
|
* page can't hold the new keys, and has to be split in turn, in which
|
||||||
* case we want to release all the locks we can.
|
* case we want to release all the locks we can.
|
||||||
*/
|
*/
|
||||||
if ((ret = __bam_pinsert(dbc, pp, lp, rp, 1)) != 0)
|
if ((ret = __bam_pinsert(dbc, pp, lp, rp, BPI_SPACEONLY)) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -349,7 +348,7 @@ __bam_page(dbc, pp, cp)
|
||||||
* a page that's not in our direct ancestry. Consider a cursor walking
|
* a page that's not in our direct ancestry. Consider a cursor walking
|
||||||
* backward through the leaf pages, that has our following page locked,
|
* backward through the leaf pages, that has our following page locked,
|
||||||
* and is waiting on a lock for the page we're splitting. In that case
|
* and is waiting on a lock for the page we're splitting. In that case
|
||||||
* we're going to deadlock here . It's probably OK, stepping backward
|
* we're going to deadlock here. It's probably OK, stepping backward
|
||||||
* through the tree isn't a common operation.
|
* through the tree isn't a common operation.
|
||||||
*/
|
*/
|
||||||
if (ISLEAF(cp->page) && NEXT_PGNO(cp->page) != PGNO_INVALID) {
|
if (ISLEAF(cp->page) && NEXT_PGNO(cp->page) != PGNO_INVALID) {
|
||||||
|
@ -685,13 +684,15 @@ __ram_root(dbc, rootp, lp, rp)
|
||||||
/*
|
/*
|
||||||
* __bam_pinsert --
|
* __bam_pinsert --
|
||||||
* Insert a new key into a parent page, completing the split.
|
* Insert a new key into a parent page, completing the split.
|
||||||
|
*
|
||||||
|
* PUBLIC: int __bam_pinsert __P((DBC *, EPG *, PAGE *, PAGE *, int));
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
__bam_pinsert(dbc, parent, lchild, rchild, space_check)
|
__bam_pinsert(dbc, parent, lchild, rchild, flags)
|
||||||
DBC *dbc;
|
DBC *dbc;
|
||||||
EPG *parent;
|
EPG *parent;
|
||||||
PAGE *lchild, *rchild;
|
PAGE *lchild, *rchild;
|
||||||
int space_check;
|
int flags;
|
||||||
{
|
{
|
||||||
BINTERNAL bi, *child_bi;
|
BINTERNAL bi, *child_bi;
|
||||||
BKEYDATA *child_bk, *tmp_bk;
|
BKEYDATA *child_bk, *tmp_bk;
|
||||||
|
@ -714,7 +715,7 @@ __bam_pinsert(dbc, parent, lchild, rchild, space_check)
|
||||||
|
|
||||||
/* If handling record numbers, count records split to the right page. */
|
/* If handling record numbers, count records split to the right page. */
|
||||||
nrecs = F_ISSET(cp, C_RECNUM) &&
|
nrecs = F_ISSET(cp, C_RECNUM) &&
|
||||||
!space_check ? __bam_total(dbp, rchild) : 0;
|
!LF_ISSET(BPI_SPACEONLY) ? __bam_total(dbp, rchild) : 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we insert the new page's first key into the parent page, which
|
* Now we insert the new page's first key into the parent page, which
|
||||||
|
@ -750,7 +751,7 @@ __bam_pinsert(dbc, parent, lchild, rchild, space_check)
|
||||||
|
|
||||||
if (P_FREESPACE(dbp, ppage) < nbytes)
|
if (P_FREESPACE(dbp, ppage) < nbytes)
|
||||||
return (DB_NEEDSPLIT);
|
return (DB_NEEDSPLIT);
|
||||||
if (space_check)
|
if (LF_ISSET(BPI_SPACEONLY))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* Add a new record for the right page. */
|
/* Add a new record for the right page. */
|
||||||
|
@ -780,7 +781,11 @@ __bam_pinsert(dbc, parent, lchild, rchild, space_check)
|
||||||
child_bk = GET_BKEYDATA(dbp, rchild, 0);
|
child_bk = GET_BKEYDATA(dbp, rchild, 0);
|
||||||
switch (B_TYPE(child_bk->type)) {
|
switch (B_TYPE(child_bk->type)) {
|
||||||
case B_KEYDATA:
|
case B_KEYDATA:
|
||||||
|
nbytes = BINTERNAL_PSIZE(child_bk->len);
|
||||||
|
nksize = child_bk->len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Prefix compression:
|
||||||
* We set t->bt_prefix to NULL if we have a comparison
|
* We set t->bt_prefix to NULL if we have a comparison
|
||||||
* callback but no prefix compression callback. But,
|
* callback but no prefix compression callback. But,
|
||||||
* if we're splitting in an off-page duplicates tree,
|
* if we're splitting in an off-page duplicates tree,
|
||||||
|
@ -792,6 +797,14 @@ __bam_pinsert(dbc, parent, lchild, rchild, space_check)
|
||||||
* as there's no way for an application to specify a
|
* as there's no way for an application to specify a
|
||||||
* prefix compression callback that corresponds to its
|
* prefix compression callback that corresponds to its
|
||||||
* comparison callback.
|
* comparison callback.
|
||||||
|
*
|
||||||
|
* No prefix compression if we don't have a compression
|
||||||
|
* function, or the key we'd compress isn't a normal
|
||||||
|
* key (for example, it references an overflow page).
|
||||||
|
*
|
||||||
|
* Generate a parent page key for the right child page
|
||||||
|
* from a comparison of the last key on the left child
|
||||||
|
* page and the first key on the right child page.
|
||||||
*/
|
*/
|
||||||
if (F_ISSET(dbc, DBC_OPD)) {
|
if (F_ISSET(dbc, DBC_OPD)) {
|
||||||
if (dbp->dup_compare == __bam_defcmp)
|
if (dbp->dup_compare == __bam_defcmp)
|
||||||
|
@ -800,13 +813,8 @@ __bam_pinsert(dbc, parent, lchild, rchild, space_check)
|
||||||
func = NULL;
|
func = NULL;
|
||||||
} else
|
} else
|
||||||
func = t->bt_prefix;
|
func = t->bt_prefix;
|
||||||
|
|
||||||
nbytes = BINTERNAL_PSIZE(child_bk->len);
|
|
||||||
nksize = child_bk->len;
|
|
||||||
if (func == NULL)
|
if (func == NULL)
|
||||||
goto noprefix;
|
goto noprefix;
|
||||||
if (ppage->prev_pgno == PGNO_INVALID && off <= 1)
|
|
||||||
goto noprefix;
|
|
||||||
tmp_bk = GET_BKEYDATA(dbp, lchild, NUM_ENT(lchild) -
|
tmp_bk = GET_BKEYDATA(dbp, lchild, NUM_ENT(lchild) -
|
||||||
(TYPE(lchild) == P_LDUP ? O_INDX : P_INDX));
|
(TYPE(lchild) == P_LDUP ? O_INDX : P_INDX));
|
||||||
if (B_TYPE(tmp_bk->type) != B_KEYDATA)
|
if (B_TYPE(tmp_bk->type) != B_KEYDATA)
|
||||||
|
@ -821,11 +829,11 @@ __bam_pinsert(dbc, parent, lchild, rchild, space_check)
|
||||||
if ((n = BINTERNAL_PSIZE(nksize)) < nbytes)
|
if ((n = BINTERNAL_PSIZE(nksize)) < nbytes)
|
||||||
nbytes = n;
|
nbytes = n;
|
||||||
else
|
else
|
||||||
noprefix: nksize = child_bk->len;
|
nksize = child_bk->len;
|
||||||
|
|
||||||
if (P_FREESPACE(dbp, ppage) < nbytes)
|
noprefix: if (P_FREESPACE(dbp, ppage) < nbytes)
|
||||||
return (DB_NEEDSPLIT);
|
return (DB_NEEDSPLIT);
|
||||||
if (space_check)
|
if (LF_ISSET(BPI_SPACEONLY))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
memset(&bi, 0, sizeof(bi));
|
memset(&bi, 0, sizeof(bi));
|
||||||
|
@ -849,7 +857,7 @@ noprefix: nksize = child_bk->len;
|
||||||
|
|
||||||
if (P_FREESPACE(dbp, ppage) < nbytes)
|
if (P_FREESPACE(dbp, ppage) < nbytes)
|
||||||
return (DB_NEEDSPLIT);
|
return (DB_NEEDSPLIT);
|
||||||
if (space_check)
|
if (LF_ISSET(BPI_SPACEONLY))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
memset(&bi, 0, sizeof(bi));
|
memset(&bi, 0, sizeof(bi));
|
||||||
|
@ -883,7 +891,7 @@ noprefix: nksize = child_bk->len;
|
||||||
|
|
||||||
if (P_FREESPACE(dbp, ppage) < nbytes)
|
if (P_FREESPACE(dbp, ppage) < nbytes)
|
||||||
return (DB_NEEDSPLIT);
|
return (DB_NEEDSPLIT);
|
||||||
if (space_check)
|
if (LF_ISSET(BPI_SPACEONLY))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* Add a new record for the right page. */
|
/* Add a new record for the right page. */
|
||||||
|
@ -904,13 +912,13 @@ noprefix: nksize = child_bk->len;
|
||||||
* If a Recno or Btree with record numbers AM page, or an off-page
|
* If a Recno or Btree with record numbers AM page, or an off-page
|
||||||
* duplicates tree, adjust the parent page's left page record count.
|
* duplicates tree, adjust the parent page's left page record count.
|
||||||
*/
|
*/
|
||||||
if (F_ISSET(cp, C_RECNUM)) {
|
if (F_ISSET(cp, C_RECNUM) && !LF_ISSET(BPI_NORECNUM)) {
|
||||||
/* Log the change. */
|
/* Log the change. */
|
||||||
if (DBC_LOGGING(dbc)) {
|
if (DBC_LOGGING(dbc)) {
|
||||||
if ((ret = __bam_cadjust_log(dbp, dbc->txn,
|
if ((ret = __bam_cadjust_log(dbp, dbc->txn,
|
||||||
&LSN(ppage), 0, PGNO(ppage),
|
&LSN(ppage), 0, PGNO(ppage), &LSN(ppage),
|
||||||
&LSN(ppage), parent->indx, -(int32_t)nrecs, 0)) != 0)
|
parent->indx, -(int32_t)nrecs, 0)) != 0)
|
||||||
return (ret);
|
return (ret);
|
||||||
} else
|
} else
|
||||||
LSN_NOT_LOGGED(LSN(ppage));
|
LSN_NOT_LOGGED(LSN(ppage));
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_stat.c,v 11.78 2004/09/22 03:31:26 bostic Exp $
|
* $Id: bt_stat.c,v 12.3 2005/06/16 20:20:23 bostic Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -155,7 +155,6 @@ meta_only:
|
||||||
|
|
||||||
/* Get metadata page statistics. */
|
/* Get metadata page statistics. */
|
||||||
sp->bt_metaflags = meta->dbmeta.flags;
|
sp->bt_metaflags = meta->dbmeta.flags;
|
||||||
sp->bt_maxkey = meta->maxkey;
|
|
||||||
sp->bt_minkey = meta->minkey;
|
sp->bt_minkey = meta->minkey;
|
||||||
sp->bt_re_len = meta->re_len;
|
sp->bt_re_len = meta->re_len;
|
||||||
sp->bt_re_pad = meta->re_pad;
|
sp->bt_re_pad = meta->re_pad;
|
||||||
|
@ -246,16 +245,12 @@ __bam_stat_print(dbc, flags)
|
||||||
}
|
}
|
||||||
__db_msg(dbenv, "%s\tByte order", s);
|
__db_msg(dbenv, "%s\tByte order", s);
|
||||||
__db_prflags(dbenv, NULL, sp->bt_metaflags, fn, NULL, "\tFlags");
|
__db_prflags(dbenv, NULL, sp->bt_metaflags, fn, NULL, "\tFlags");
|
||||||
if (dbp->type == DB_BTREE) {
|
if (dbp->type == DB_BTREE)
|
||||||
#ifdef NOT_IMPLEMENTED
|
|
||||||
__db_dl(dbenv, "Maximum keys per-page", (u_long)sp->bt_maxkey);
|
|
||||||
#endif
|
|
||||||
__db_dl(dbenv, "Minimum keys per-page", (u_long)sp->bt_minkey);
|
__db_dl(dbenv, "Minimum keys per-page", (u_long)sp->bt_minkey);
|
||||||
}
|
|
||||||
if (dbp->type == DB_RECNO) {
|
if (dbp->type == DB_RECNO) {
|
||||||
__db_dl(dbenv,
|
__db_dl(dbenv,
|
||||||
"Fixed-length record size", (u_long)sp->bt_re_len);
|
"Fixed-length record size", (u_long)sp->bt_re_len);
|
||||||
__db_dl(dbenv,
|
__db_msg(dbenv,
|
||||||
"%#x\tFixed-length record pad", (u_int)sp->bt_re_pad);
|
"%#x\tFixed-length record pad", (u_int)sp->bt_re_pad);
|
||||||
}
|
}
|
||||||
__db_dl(dbenv,
|
__db_dl(dbenv,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_upgrade.c,v 11.30 2004/01/28 03:35:49 bostic Exp $
|
* $Id: bt_upgrade.c,v 12.1 2005/06/16 20:20:23 bostic Exp $
|
||||||
*/
|
*/
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1999-2004
|
* Copyright (c) 1999-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: bt_verify.c,v 1.97 2004/10/11 18:47:46 bostic Exp $
|
* $Id: bt_verify.c,v 12.13 2005/11/11 20:27:49 ubell Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "db_config.h"
|
#include "db_config.h"
|
||||||
|
@ -89,10 +89,8 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags)
|
||||||
} else
|
} else
|
||||||
pip->bt_minkey = meta->minkey;
|
pip->bt_minkey = meta->minkey;
|
||||||
|
|
||||||
/* bt_maxkey: unsupported so no constraints. */
|
|
||||||
pip->bt_maxkey = meta->maxkey;
|
|
||||||
|
|
||||||
/* re_len: no constraints on this (may be zero or huge--we make rope) */
|
/* re_len: no constraints on this (may be zero or huge--we make rope) */
|
||||||
|
pip->re_pad = meta->re_pad;
|
||||||
pip->re_len = meta->re_len;
|
pip->re_len = meta->re_len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1618,8 +1616,17 @@ bad_prev: isbad = 1;
|
||||||
if (relenp)
|
if (relenp)
|
||||||
*relenp = relen;
|
*relenp = relen;
|
||||||
}
|
}
|
||||||
if (LF_ISSET(ST_RECNUM))
|
if (LF_ISSET(ST_RECNUM)) {
|
||||||
|
if (child->nrecs != child_nrecs) {
|
||||||
|
isbad = 1;
|
||||||
|
EPRINT((dbenv,
|
||||||
|
"Page %lu: record count incorrect: actual %lu, in record %lu",
|
||||||
|
(u_long)child->pgno,
|
||||||
|
(u_long)child_nrecs,
|
||||||
|
(u_long)child->nrecs));
|
||||||
|
}
|
||||||
nrecs += child_nrecs;
|
nrecs += child_nrecs;
|
||||||
|
}
|
||||||
if (isbad == 0 && level != child_level + 1) {
|
if (isbad == 0 && level != child_level + 1) {
|
||||||
isbad = 1;
|
isbad = 1;
|
||||||
EPRINT((dbenv,
|
EPRINT((dbenv,
|
||||||
|
@ -2037,38 +2044,36 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
|
||||||
DBT *key;
|
DBT *key;
|
||||||
u_int32_t flags;
|
u_int32_t flags;
|
||||||
{
|
{
|
||||||
DBT dbt, unkdbt;
|
|
||||||
DB_ENV *dbenv;
|
|
||||||
BKEYDATA *bk;
|
BKEYDATA *bk;
|
||||||
BOVERFLOW *bo;
|
BOVERFLOW *bo;
|
||||||
|
DBT dbt, unknown_key, unknown_data;
|
||||||
|
DB_ENV *dbenv;
|
||||||
VRFY_ITEM *pgmap;
|
VRFY_ITEM *pgmap;
|
||||||
db_indx_t i, beg, end, *inp;
|
db_indx_t i, last, beg, end, *inp;
|
||||||
u_int32_t himark;
|
u_int32_t himark;
|
||||||
void *ovflbuf;
|
void *ovflbuf;
|
||||||
int t_ret, ret, err_ret;
|
int ret, t_ret, t2_ret;
|
||||||
|
|
||||||
dbenv = dbp->dbenv;
|
dbenv = dbp->dbenv;
|
||||||
|
|
||||||
/* Shut up lint. */
|
|
||||||
COMPQUIET(end, 0);
|
|
||||||
|
|
||||||
ovflbuf = pgmap = NULL;
|
ovflbuf = pgmap = NULL;
|
||||||
err_ret = ret = 0;
|
|
||||||
inp = P_INP(dbp, h);
|
inp = P_INP(dbp, h);
|
||||||
|
|
||||||
memset(&dbt, 0, sizeof(DBT));
|
memset(&dbt, 0, sizeof(DBT));
|
||||||
dbt.flags = DB_DBT_REALLOC;
|
dbt.flags = DB_DBT_REALLOC;
|
||||||
|
|
||||||
memset(&unkdbt, 0, sizeof(DBT));
|
memset(&unknown_key, 0, sizeof(DBT));
|
||||||
unkdbt.size = (u_int32_t)(strlen("UNKNOWN") + 1);
|
unknown_key.size = (u_int32_t)strlen("UNKNOWN_KEY");
|
||||||
unkdbt.data = "UNKNOWN";
|
unknown_key.data = "UNKNOWN_KEY";
|
||||||
|
memset(&unknown_data, 0, sizeof(DBT));
|
||||||
|
unknown_data.size = (u_int32_t)strlen("UNKNOWN_DATA");
|
||||||
|
unknown_data.data = "UNKNOWN_DATA";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a buffer for overflow items. Start at one page;
|
* Allocate a buffer for overflow items. Start at one page;
|
||||||
* __db_safe_goff will realloc as needed.
|
* __db_safe_goff will realloc as needed.
|
||||||
*/
|
*/
|
||||||
if ((ret = __os_malloc(dbenv, dbp->pgsize, &ovflbuf)) != 0)
|
if ((ret = __os_malloc(dbenv, dbp->pgsize, &ovflbuf)) != 0)
|
||||||
return (ret);
|
goto err;
|
||||||
|
|
||||||
if (LF_ISSET(DB_AGGRESSIVE) && (ret =
|
if (LF_ISSET(DB_AGGRESSIVE) && (ret =
|
||||||
__os_calloc(dbenv, dbp->pgsize, sizeof(pgmap[0]), &pgmap)) != 0)
|
__os_calloc(dbenv, dbp->pgsize, sizeof(pgmap[0]), &pgmap)) != 0)
|
||||||
|
@ -2077,161 +2082,185 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
|
||||||
/*
|
/*
|
||||||
* Loop through the inp array, spitting out key/data pairs.
|
* Loop through the inp array, spitting out key/data pairs.
|
||||||
*
|
*
|
||||||
* If we're salvaging normally, loop from 0 through NUM_ENT(h).
|
* If we're salvaging normally, loop from 0 through NUM_ENT(h). If
|
||||||
* If we're being aggressive, loop until we hit the end of the page--
|
* we're being aggressive, loop until we hit the end of the page --
|
||||||
* NUM_ENT() may be bogus.
|
* NUM_ENT() may be bogus.
|
||||||
*/
|
*/
|
||||||
himark = dbp->pgsize;
|
himark = dbp->pgsize;
|
||||||
for (i = 0;; i += O_INDX) {
|
for (i = 0, last = UINT16_MAX;; i += O_INDX) {
|
||||||
/* If we're not aggressive, break when we hit NUM_ENT(h). */
|
/* If we're not aggressive, break when we hit NUM_ENT(h). */
|
||||||
if (!LF_ISSET(DB_AGGRESSIVE) && i >= NUM_ENT(h))
|
if (!LF_ISSET(DB_AGGRESSIVE) && i >= NUM_ENT(h))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Verify the current item. */
|
/* Verify the current item. */
|
||||||
ret = __db_vrfy_inpitem(dbp,
|
t_ret =
|
||||||
h, pgno, i, 1, flags, &himark, NULL);
|
__db_vrfy_inpitem(dbp, h, pgno, i, 1, flags, &himark, NULL);
|
||||||
/* If this returned a fatality, it's time to break. */
|
|
||||||
if (ret == DB_VERIFY_FATAL) {
|
if (t_ret != 0) {
|
||||||
/*
|
/*
|
||||||
* Don't return DB_VERIFY_FATAL; it's private
|
* If this is a btree leaf and we've printed out a key
|
||||||
* and means only that we can't go on with this
|
* but not its associated data item, fix this imbalance
|
||||||
* page, not with the whole database. It's
|
* by printing an "UNKNOWN_DATA".
|
||||||
* not even an error if we've run into it
|
|
||||||
* after NUM_ENT(h).
|
|
||||||
*/
|
*/
|
||||||
ret = (i < NUM_ENT(h)) ? DB_VERIFY_BAD : 0;
|
if (pgtype == P_LBTREE && i % P_INDX == 1 &&
|
||||||
break;
|
last == i - 1 && (t2_ret = __db_vrfy_prdbt(
|
||||||
|
&unknown_data,
|
||||||
|
0, " ", handle, callback, 0, vdp)) != 0) {
|
||||||
|
if (ret == 0)
|
||||||
|
ret = t2_ret;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't return DB_VERIFY_FATAL; it's private and means
|
||||||
|
* only that we can't go on with this page, not with
|
||||||
|
* the whole database. It's not even an error if we've
|
||||||
|
* run into it after NUM_ENT(h).
|
||||||
|
*/
|
||||||
|
if (t_ret == DB_VERIFY_FATAL) {
|
||||||
|
if (i < NUM_ENT(h) && ret == 0)
|
||||||
|
ret = DB_VERIFY_BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this returned 0, it's safe to print or (carefully)
|
* If this returned 0, it's safe to print or (carefully)
|
||||||
* try to fetch.
|
* try to fetch.
|
||||||
|
*
|
||||||
|
* We only print deleted items if DB_AGGRESSIVE is set.
|
||||||
*/
|
*/
|
||||||
if (ret == 0) {
|
bk = GET_BKEYDATA(dbp, h, i);
|
||||||
/*
|
if (!LF_ISSET(DB_AGGRESSIVE) && B_DISSET(bk->type))
|
||||||
* We only want to print deleted items if
|
continue;
|
||||||
* DB_AGGRESSIVE is set.
|
|
||||||
*/
|
|
||||||
bk = GET_BKEYDATA(dbp, h, i);
|
|
||||||
if (!LF_ISSET(DB_AGGRESSIVE) && B_DISSET(bk->type))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're going to go try to print the next item. If
|
* If this is a btree leaf and we're about to print out a data
|
||||||
* key is non-NULL, we're a dup page, so we've got to
|
* item for which we didn't print out a key, fix this imbalance
|
||||||
* print the key first, unless SA_SKIPFIRSTKEY is set
|
* by printing an "UNKNOWN_KEY".
|
||||||
* and we're on the first entry.
|
*/
|
||||||
*/
|
if (pgtype == P_LBTREE && i % P_INDX == 1 &&
|
||||||
if (key != NULL &&
|
last != i - 1 && (t_ret = __db_vrfy_prdbt(
|
||||||
(i != 0 || !LF_ISSET(SA_SKIPFIRSTKEY)))
|
&unknown_key, 0, " ", handle, callback, 0, vdp)) != 0) {
|
||||||
if ((ret = __db_vrfy_prdbt(key,
|
if (ret == 0)
|
||||||
0, " ", handle, callback, 0, vdp)) != 0)
|
ret = t_ret;
|
||||||
err_ret = ret;
|
goto err;
|
||||||
|
}
|
||||||
|
last = i;
|
||||||
|
|
||||||
beg = inp[i];
|
/*
|
||||||
switch (B_TYPE(bk->type)) {
|
* We're going to go try to print the next item. If key is
|
||||||
case B_DUPLICATE:
|
* non-NULL, we're a dup page, so we've got to print the key
|
||||||
end = beg + BOVERFLOW_SIZE - 1;
|
* first, unless SA_SKIPFIRSTKEY is set and we're on the first
|
||||||
/*
|
* entry.
|
||||||
* If we're not on a normal btree leaf page,
|
*/
|
||||||
* there shouldn't be off-page
|
if (key != NULL && (i != 0 || !LF_ISSET(SA_SKIPFIRSTKEY)))
|
||||||
* dup sets. Something's confused; just
|
if ((t_ret = __db_vrfy_prdbt(key,
|
||||||
* drop it, and the code to pick up unlinked
|
0, " ", handle, callback, 0, vdp)) != 0) {
|
||||||
* offpage dup sets will print it out
|
if (ret == 0)
|
||||||
* with key "UNKNOWN" later.
|
ret = t_ret;
|
||||||
*/
|
goto err;
|
||||||
if (pgtype != P_LBTREE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
bo = (BOVERFLOW *)bk;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the page number is unreasonable, or
|
|
||||||
* if this is supposed to be a key item,
|
|
||||||
* just spit out "UNKNOWN"--the best we
|
|
||||||
* can do is run into the data items in the
|
|
||||||
* unlinked offpage dup pass.
|
|
||||||
*/
|
|
||||||
if (!IS_VALID_PGNO(bo->pgno) ||
|
|
||||||
(i % P_INDX == 0)) {
|
|
||||||
/* Not much to do on failure. */
|
|
||||||
if ((ret =
|
|
||||||
__db_vrfy_prdbt(&unkdbt, 0, " ",
|
|
||||||
handle, callback, 0, vdp)) != 0)
|
|
||||||
err_ret = ret;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = __db_salvage_duptree(dbp,
|
|
||||||
vdp, bo->pgno, &dbt, handle, callback,
|
|
||||||
flags | SA_SKIPFIRSTKEY)) != 0)
|
|
||||||
err_ret = ret;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case B_KEYDATA:
|
|
||||||
end = (db_indx_t)DB_ALIGN(
|
|
||||||
beg + bk->len, sizeof(u_int32_t)) - 1;
|
|
||||||
dbt.data = bk->data;
|
|
||||||
dbt.size = bk->len;
|
|
||||||
if ((ret = __db_vrfy_prdbt(&dbt,
|
|
||||||
0, " ", handle, callback, 0, vdp)) != 0)
|
|
||||||
err_ret = ret;
|
|
||||||
break;
|
|
||||||
case B_OVERFLOW:
|
|
||||||
end = beg + BOVERFLOW_SIZE - 1;
|
|
||||||
bo = (BOVERFLOW *)bk;
|
|
||||||
if ((ret = __db_safe_goff(dbp, vdp,
|
|
||||||
bo->pgno, &dbt, &ovflbuf, flags)) != 0) {
|
|
||||||
err_ret = ret;
|
|
||||||
/* We care about err_ret more. */
|
|
||||||
(void)__db_vrfy_prdbt(&unkdbt, 0, " ",
|
|
||||||
handle, callback, 0, vdp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((ret = __db_vrfy_prdbt(&dbt,
|
|
||||||
0, " ", handle, callback, 0, vdp)) != 0)
|
|
||||||
err_ret = ret;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/*
|
|
||||||
* We should never get here; __db_vrfy_inpitem
|
|
||||||
* should not be returning 0 if bk->type
|
|
||||||
* is unrecognizable.
|
|
||||||
*/
|
|
||||||
DB_ASSERT(0);
|
|
||||||
return (EINVAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
beg = inp[i];
|
||||||
|
switch (B_TYPE(bk->type)) {
|
||||||
|
case B_DUPLICATE:
|
||||||
|
end = beg + BOVERFLOW_SIZE - 1;
|
||||||
/*
|
/*
|
||||||
* If we're being aggressive, mark the beginning
|
* If we're not on a normal btree leaf page, there
|
||||||
* and end of the item; we'll come back and print
|
* shouldn't be off-page dup sets. Something's
|
||||||
* whatever "junk" is in the gaps in case we had
|
* confused; just drop it, and the code to pick up
|
||||||
* any bogus inp elements and thereby missed stuff.
|
* unlinked offpage dup sets will print it out
|
||||||
|
* with key "UNKNOWN" later.
|
||||||
*/
|
*/
|
||||||
if (LF_ISSET(DB_AGGRESSIVE)) {
|
if (pgtype != P_LBTREE)
|
||||||
pgmap[beg] = VRFY_ITEM_BEGIN;
|
break;
|
||||||
pgmap[end] = VRFY_ITEM_END;
|
|
||||||
|
bo = (BOVERFLOW *)bk;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the page number is unreasonable, or if this is
|
||||||
|
* supposed to be a key item, output "UNKNOWN_KEY" --
|
||||||
|
* the best we can do is run into the data items in
|
||||||
|
* the unlinked offpage dup pass.
|
||||||
|
*/
|
||||||
|
if (!IS_VALID_PGNO(bo->pgno) || (i % P_INDX == 0)) {
|
||||||
|
/* Not much to do on failure. */
|
||||||
|
if ((t_ret = __db_vrfy_prdbt(&unknown_key,
|
||||||
|
0, " ", handle, callback, 0, vdp)) != 0) {
|
||||||
|
if (ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Don't stop on error. */
|
||||||
|
if ((t_ret = __db_salvage_duptree(dbp,
|
||||||
|
vdp, bo->pgno, &dbt, handle, callback,
|
||||||
|
flags | SA_SKIPFIRSTKEY)) != 0 && ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case B_KEYDATA:
|
||||||
|
end = (db_indx_t)DB_ALIGN(
|
||||||
|
beg + bk->len, sizeof(u_int32_t)) - 1;
|
||||||
|
dbt.data = bk->data;
|
||||||
|
dbt.size = bk->len;
|
||||||
|
if ((t_ret = __db_vrfy_prdbt(&dbt,
|
||||||
|
0, " ", handle, callback, 0, vdp)) != 0) {
|
||||||
|
if (ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_OVERFLOW:
|
||||||
|
end = beg + BOVERFLOW_SIZE - 1;
|
||||||
|
bo = (BOVERFLOW *)bk;
|
||||||
|
|
||||||
|
/* Don't stop on error. */
|
||||||
|
if ((t_ret = __db_safe_goff(dbp, vdp,
|
||||||
|
bo->pgno, &dbt, &ovflbuf, flags)) != 0 && ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
if ((t_ret = __db_vrfy_prdbt(
|
||||||
|
t_ret == 0 ? &dbt : &unknown_key,
|
||||||
|
0, " ", handle, callback, 0, vdp)) != 0 && ret == 0)
|
||||||
|
ret = t_ret;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* We should never get here; __db_vrfy_inpitem should
|
||||||
|
* not be returning 0 if bk->type is unrecognizable.
|
||||||
|
*/
|
||||||
|
DB_ASSERT(0);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're being aggressive, mark the beginning and end of
|
||||||
|
* the item; we'll come back and print whatever "junk" is in
|
||||||
|
* the gaps in case we had any bogus inp elements and thereby
|
||||||
|
* missed stuff.
|
||||||
|
*/
|
||||||
|
if (LF_ISSET(DB_AGGRESSIVE)) {
|
||||||
|
pgmap[beg] = VRFY_ITEM_BEGIN;
|
||||||
|
pgmap[end] = VRFY_ITEM_END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If i is odd and this is a btree leaf, we've printed out a key but not
|
|
||||||
* a datum; fix this imbalance by printing an "UNKNOWN".
|
|
||||||
*/
|
|
||||||
if (pgtype == P_LBTREE && (i % P_INDX == 1) && ((ret =
|
|
||||||
__db_vrfy_prdbt(&unkdbt, 0, " ", handle, callback, 0, vdp)) != 0))
|
|
||||||
err_ret = ret;
|
|
||||||
|
|
||||||
err: if (pgmap != NULL)
|
err: if (pgmap != NULL)
|
||||||
__os_free(dbenv, pgmap);
|
__os_free(dbenv, pgmap);
|
||||||
__os_free(dbenv, ovflbuf);
|
if (ovflbuf != NULL)
|
||||||
|
__os_free(dbenv, ovflbuf);
|
||||||
|
|
||||||
/* Mark this page as done. */
|
/* Mark this page as done. */
|
||||||
if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0)
|
if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0)
|
||||||
return (t_ret);
|
ret = t_ret;
|
||||||
|
|
||||||
return ((err_ret != 0) ? err_ret : ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1996-2004
|
* Copyright (c) 1996-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: btree.src,v 10.42 2004/06/17 17:35:12 bostic Exp $
|
* $Id: btree.src,v 12.3 2005/08/08 03:37:05 ubell Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PREFIX __bam
|
PREFIX __bam
|
||||||
|
@ -210,10 +210,10 @@ END
|
||||||
BEGIN relink 147
|
BEGIN relink 147
|
||||||
/* Fileid of db affected. */
|
/* Fileid of db affected. */
|
||||||
DB fileid int32_t ld
|
DB fileid int32_t ld
|
||||||
/* The page being changed. */
|
/* The page being removed. */
|
||||||
ARG pgno db_pgno_t lu
|
ARG pgno db_pgno_t lu
|
||||||
/* The page's original lsn. */
|
/* The new page number, if any. */
|
||||||
POINTER lsn DB_LSN * lu
|
ARG new_pgno db_pgno_t lu
|
||||||
/* The previous page. */
|
/* The previous page. */
|
||||||
ARG prev db_pgno_t lu
|
ARG prev db_pgno_t lu
|
||||||
/* The previous page's original lsn. */
|
/* The previous page's original lsn. */
|
||||||
|
@ -223,3 +223,30 @@ ARG next db_pgno_t lu
|
||||||
/* The previous page's original lsn. */
|
/* The previous page's original lsn. */
|
||||||
POINTER lsn_next DB_LSN * lu
|
POINTER lsn_next DB_LSN * lu
|
||||||
END
|
END
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BTREE-merge -- Handles merging of pages during a compaction.
|
||||||
|
*/
|
||||||
|
BEGIN merge 148
|
||||||
|
DB fileid int32_t ld
|
||||||
|
ARG pgno db_pgno_t lu
|
||||||
|
POINTER lsn DB_LSN * lu
|
||||||
|
ARG npgno db_pgno_t lu
|
||||||
|
POINTER nlsn DB_LSN * lu
|
||||||
|
DBT hdr DBT s
|
||||||
|
DBT data DBT s
|
||||||
|
DBT ind DBT s
|
||||||
|
END
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BTREE-pgno -- Handles replacing a page number in the record
|
||||||
|
* refernece on pgno by indx.
|
||||||
|
*/
|
||||||
|
BEGIN pgno 149
|
||||||
|
DB fileid int32_t ld
|
||||||
|
ARG pgno db_pgno_t lu
|
||||||
|
POINTER lsn DB_LSN * lu
|
||||||
|
ARG indx u_int32_t lu
|
||||||
|
ARG opgno db_pgno_t lu
|
||||||
|
ARG npgno db_pgno_t lu
|
||||||
|
END
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
Document file - DO NOT EDIT
|
|
||||||
|
|
||||||
<BEGIN> CORE_INFO_TYPE
|
|
||||||
Workspace
|
|
||||||
<END>
|
|
||||||
|
|
||||||
<BEGIN> CORE_INFO_VERSION
|
|
||||||
2.0
|
|
||||||
<END>
|
|
||||||
|
|
||||||
<BEGIN> projectList
|
|
||||||
$(PRJ_DIR)/BerkeleyDB.wpj \
|
|
||||||
$(PRJ_DIR)/db_archive/db_archive.wpj \
|
|
||||||
$(PRJ_DIR)/db_checkpoint/db_checkpoint.wpj \
|
|
||||||
$(PRJ_DIR)/db_deadlock/db_deadlock.wpj \
|
|
||||||
$(PRJ_DIR)/db_dump/db_dump.wpj \
|
|
||||||
$(PRJ_DIR)/db_load/db_load.wpj \
|
|
||||||
$(PRJ_DIR)/db_printlog/db_printlog.wpj \
|
|
||||||
$(PRJ_DIR)/db_recover/db_recover.wpj \
|
|
||||||
$(PRJ_DIR)/db_stat/db_stat.wpj \
|
|
||||||
$(PRJ_DIR)/db_upgrade/db_upgrade.wpj \
|
|
||||||
$(PRJ_DIR)/db_verify/db_verify.wpj \
|
|
||||||
$(PRJ_DIR)/dbdemo/dbdemo.wpj
|
|
||||||
<END>
|
|
||||||
|
|
||||||
<BEGIN> userComments
|
|
||||||
|
|
||||||
<END>
|
|
||||||
|
|
|
@ -1,251 +0,0 @@
|
||||||
/*-
|
|
||||||
* See the file LICENSE for redistribution information.
|
|
||||||
*
|
|
||||||
* Copyright (c) 1996-2004
|
|
||||||
* Sleepycat Software. All rights reserved.
|
|
||||||
*
|
|
||||||
* $Id: db_deadlock.c,v 11.45 2004/03/24 15:13:12 bostic Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "db_config.h"
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
static const char copyright[] =
|
|
||||||
"Copyright (c) 1996-2004\nSleepycat Software Inc. All rights reserved.\n";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_SYSTEM_INCLUDES
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "db_int.h"
|
|
||||||
|
|
||||||
int db_deadlock_main __P((int, char *[]));
|
|
||||||
int db_deadlock_usage __P((void));
|
|
||||||
int db_deadlock_version_check __P((const char *));
|
|
||||||
|
|
||||||
int
|
|
||||||
db_deadlock(args)
|
|
||||||
char *args;
|
|
||||||
{
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
|
|
||||||
__db_util_arg("db_deadlock", args, &argc, &argv);
|
|
||||||
return (db_deadlock_main(argc, argv) ? EXIT_FAILURE : EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#define ERROR_RETURN ERROR
|
|
||||||
|
|
||||||
int
|
|
||||||
db_deadlock_main(argc, argv)
|
|
||||||
int argc;
|
|
||||||
char *argv[];
|
|
||||||
{
|
|
||||||
extern char *optarg;
|
|
||||||
extern int optind, __db_getopt_reset;
|
|
||||||
const char *progname = "db_deadlock";
|
|
||||||
DB_ENV *dbenv;
|
|
||||||
u_int32_t atype;
|
|
||||||
time_t now;
|
|
||||||
u_long secs, usecs;
|
|
||||||
int ch, exitval, ret, verbose;
|
|
||||||
char *home, *logfile, *str;
|
|
||||||
|
|
||||||
if ((ret = db_deadlock_version_check(progname)) != 0)
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
dbenv = NULL;
|
|
||||||
atype = DB_LOCK_DEFAULT;
|
|
||||||
home = logfile = NULL;
|
|
||||||
secs = usecs = 0;
|
|
||||||
exitval = verbose = 0;
|
|
||||||
__db_getopt_reset = 1;
|
|
||||||
while ((ch = getopt(argc, argv, "a:h:L:t:Vvw")) != EOF)
|
|
||||||
switch (ch) {
|
|
||||||
case 'a':
|
|
||||||
switch (optarg[0]) {
|
|
||||||
case 'e':
|
|
||||||
atype = DB_LOCK_EXPIRE;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
atype = DB_LOCK_MAXLOCKS;
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
atype = DB_LOCK_MINLOCKS;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
atype = DB_LOCK_OLDEST;
|
|
||||||
break;
|
|
||||||
case 'W':
|
|
||||||
atype = DB_LOCK_MAXWRITE;
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
atype = DB_LOCK_MINWRITE;
|
|
||||||
break;
|
|
||||||
case 'y':
|
|
||||||
atype = DB_LOCK_YOUNGEST;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (db_deadlock_usage());
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
if (optarg[1] != '\0')
|
|
||||||
return (db_deadlock_usage());
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
home = optarg;
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
logfile = optarg;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
if ((str = strchr(optarg, '.')) != NULL) {
|
|
||||||
*str++ = '\0';
|
|
||||||
if (*str != '\0' && __db_getulong(
|
|
||||||
NULL, progname, str, 0, LONG_MAX, &usecs))
|
|
||||||
return (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if (*optarg != '\0' && __db_getulong(
|
|
||||||
NULL, progname, optarg, 0, LONG_MAX, &secs))
|
|
||||||
return (EXIT_FAILURE);
|
|
||||||
if (secs == 0 && usecs == 0)
|
|
||||||
return (db_deadlock_usage());
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'V':
|
|
||||||
printf("%s\n", db_version(NULL, NULL, NULL));
|
|
||||||
return (EXIT_SUCCESS);
|
|
||||||
case 'v':
|
|
||||||
verbose = 1;
|
|
||||||
break;
|
|
||||||
case 'w': /* Undocumented. */
|
|
||||||
/* Detect every 100ms (100000 us) when polling. */
|
|
||||||
secs = 0;
|
|
||||||
usecs = 100000;
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
default:
|
|
||||||
return (db_deadlock_usage());
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc != 0)
|
|
||||||
return (db_deadlock_usage());
|
|
||||||
|
|
||||||
/* Handle possible interruptions. */
|
|
||||||
__db_util_siginit();
|
|
||||||
|
|
||||||
/* Log our process ID. */
|
|
||||||
if (logfile != NULL && __db_util_logset(progname, logfile))
|
|
||||||
goto shutdown;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create an environment object and initialize it for error
|
|
||||||
* reporting.
|
|
||||||
*/
|
|
||||||
if ((ret = db_env_create(&dbenv, 0)) != 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: db_env_create: %s\n", progname, db_strerror(ret));
|
|
||||||
goto shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbenv->set_errfile(dbenv, stderr);
|
|
||||||
dbenv->set_errpfx(dbenv, progname);
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
(void)dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK, 1);
|
|
||||||
(void)dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* An environment is required. */
|
|
||||||
if ((ret =
|
|
||||||
dbenv->open(dbenv, home, DB_INIT_LOCK | DB_USE_ENVIRON, 0)) != 0) {
|
|
||||||
dbenv->err(dbenv, ret, "open");
|
|
||||||
goto shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!__db_util_interrupted()) {
|
|
||||||
if (verbose) {
|
|
||||||
(void)time(&now);
|
|
||||||
dbenv->errx(dbenv, "running at %.24s", ctime(&now));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = dbenv->lock_detect(dbenv, 0, atype, NULL)) != 0) {
|
|
||||||
dbenv->err(dbenv, ret, "DB_ENV->lock_detect");
|
|
||||||
goto shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make a pass every "secs" secs and "usecs" usecs. */
|
|
||||||
if (secs == 0 && usecs == 0)
|
|
||||||
break;
|
|
||||||
__os_sleep(dbenv, secs, usecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0) {
|
|
||||||
shutdown: exitval = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clean up the logfile. */
|
|
||||||
if (logfile != NULL)
|
|
||||||
(void)remove(logfile);
|
|
||||||
|
|
||||||
/* Clean up the environment. */
|
|
||||||
if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
|
|
||||||
exitval = 1;
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: dbenv->close: %s\n", progname, db_strerror(ret));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Resend any caught signal. */
|
|
||||||
__db_util_sigresend();
|
|
||||||
|
|
||||||
return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
db_deadlock_usage()
|
|
||||||
{
|
|
||||||
(void)fprintf(stderr, "%s\n\t%s\n",
|
|
||||||
"usage: db_deadlock [-Vv]",
|
|
||||||
"[-a e | m | n | o | W | w | y] [-h home] [-L file] [-t sec.usec]");
|
|
||||||
return (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
db_deadlock_version_check(progname)
|
|
||||||
const char *progname;
|
|
||||||
{
|
|
||||||
int v_major, v_minor, v_patch;
|
|
||||||
|
|
||||||
/* Make sure we're loaded with the right version of the DB library. */
|
|
||||||
(void)db_version(&v_major, &v_minor, &v_patch);
|
|
||||||
if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: version %d.%d doesn't match library version %d.%d\n",
|
|
||||||
progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
|
|
||||||
v_major, v_minor);
|
|
||||||
return (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
This README describes the steps needed to run a demo example of BerkeleyDB.
|
|
||||||
|
|
||||||
1. Read the pages in the Reference Guide that describe building
|
|
||||||
BerkeleyDB on VxWorks:
|
|
||||||
|
|
||||||
$(WIND_BASE)/target/src/BerkeleyDB/docs/ref/build_vxworks/intro.html
|
|
||||||
$(WIND_BASE)/target/src/BerkeleyDB/docs/ref/build_vxworks/notes.html
|
|
||||||
$(WIND_BASE)/target/src/BerkeleyDB/docs/ref/build_vxworks/faq.html
|
|
||||||
|
|
||||||
2. Launch Tornado 2.0 and open up the BerkeleyDB project.
|
|
||||||
|
|
||||||
3. Add the demo project to that workspace:
|
|
||||||
|
|
||||||
$(WIND_BASE)/target/src/BerkeleyDB/build_vxworks/demo/dbdemo.wpj
|
|
||||||
|
|
||||||
4. Build BerkeleyDB as described in the Reference Guide.
|
|
||||||
|
|
||||||
5. Build the dbdemo project.
|
|
||||||
|
|
||||||
6. Download BerkeleyDB onto the target.
|
|
||||||
|
|
||||||
7. Download the dbdemo project onto the target.
|
|
||||||
|
|
||||||
8. Open a windsh to the target and run the demo:
|
|
||||||
|
|
||||||
-> dbdemo "<pathname>/<dbname>"
|
|
||||||
|
|
||||||
Where pathname is a pathname string pointing to a directory that the
|
|
||||||
demo can create a database in. That directory should already exist.
|
|
||||||
The dbname is the name for the database. For example:
|
|
||||||
|
|
||||||
-> dbdemo "/tmp/demo.db"
|
|
||||||
|
|
||||||
9. The demo program will ask for input. You can type in any string.
|
|
||||||
The program will add an entry to the database with that string as
|
|
||||||
the key and the reverse of that string as the data item for that key.
|
|
||||||
It will continue asking for input until you hit ^D or enter "quit".
|
|
||||||
Upon doing so, the demo program will display all the keys you have
|
|
||||||
entered as input and their data items.
|
|
|
@ -21,12 +21,15 @@ Package=<4>
|
||||||
Project_Dep_Name db_deadlock
|
Project_Dep_Name db_deadlock
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name DB_DLL
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_dump
|
Project_Dep_Name db_dump
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_hotbackup
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_load
|
Project_Dep_Name db_load
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
|
@ -45,7 +48,7 @@ Package=<4>
|
||||||
Project_Dep_Name db_verify
|
Project_Dep_Name db_verify
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name DB_Static
|
Project_Dep_Name db_static
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name ex_access
|
Project_Dep_Name ex_access
|
||||||
|
@ -63,9 +66,18 @@ Package=<4>
|
||||||
Project_Dep_Name ex_mpool
|
Project_Dep_Name ex_mpool
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name ex_sequence
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
Project_Dep_Name ex_tpcb
|
Project_Dep_Name ex_tpcb
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name example_database_load
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name example_database_read
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
Project_Dep_Name excxx_access
|
Project_Dep_Name excxx_access
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
|
@ -81,10 +93,31 @@ Package=<4>
|
||||||
Project_Dep_Name excxx_mpool
|
Project_Dep_Name excxx_mpool
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name excxx_sequence
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
Project_Dep_Name excxx_tpcb
|
Project_Dep_Name excxx_tpcb
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name excxx_example_database_load
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name excxx_example_database_read
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name ex_repquote
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name ex_txnguide
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name ex_txnguide_inmem
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name excxx_txnguide
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name excxx_txnguide_inmem
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -99,7 +132,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -114,7 +147,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -129,7 +162,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name DB_DLL
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -156,7 +189,22 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "db_hotbackup"=.\db_hotbackup.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -168,29 +216,11 @@ Package=<5>
|
||||||
{{{
|
{{{
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
Package=<4>
|
|
||||||
{{{
|
|
||||||
Begin Project Dependency
|
|
||||||
Project_Dep_Name DB_DLL
|
|
||||||
End Project Dependency
|
|
||||||
}}}
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
Project: "db_lib"=.\db_lib.dsp - Package Owner=<4>
|
|
||||||
|
|
||||||
Package=<5>
|
|
||||||
{{{
|
|
||||||
}}}
|
|
||||||
|
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_dll
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
|
||||||
Project_Dep_Name db_static
|
|
||||||
End Project Dependency
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -204,7 +234,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -219,7 +249,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -234,12 +264,24 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "db_small"=.\db_small.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
Project: "db_stat"=.\db_stat.dsp - Package Owner=<4>
|
Project: "db_stat"=.\db_stat.dsp - Package Owner=<4>
|
||||||
|
|
||||||
Package=<5>
|
Package=<5>
|
||||||
|
@ -249,7 +291,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -276,7 +318,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name DB_DLL
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -309,7 +351,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -324,7 +366,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -339,7 +381,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -354,7 +396,58 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "ex_csvcode"=.\ex_csvcode.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "ex_csvload"=.\ex_csvload.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name ex_csvcode
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "ex_csvquery"=.\ex_csvquery.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name ex_csvcode
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -369,7 +462,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -384,7 +477,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -399,7 +492,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -414,7 +507,22 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "ex_sequence"=.\ex_sequence.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -429,7 +537,67 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "ex_txnguide"=.\ex_txnguide.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "ex_txnguide_inmem"=.\ex_txnguide_inmem.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "example_database_load"=.\example_database_load.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "example_database_read"=.\example_database_read.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -444,7 +612,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -459,7 +627,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -474,7 +642,37 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "excxx_example_database_load"=.\excxx_example_database_load.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "excxx_example_database_read"=.\excxx_example_database_read.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -489,7 +687,7 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -504,7 +702,22 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "excxx_sequence"=.\excxx_sequence.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -519,7 +732,37 @@ Package=<5>
|
||||||
Package=<4>
|
Package=<4>
|
||||||
{{{
|
{{{
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name db_lib
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "excxx_txnguide"=.\excxx_txnguide.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "excxx_txnguide_inmem"=.\excxx_txnguide_inmem.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name db_dll
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||||
|
|
||||||
CFG=@project_name@ - Win32 Debug Static
|
CFG=@project_name@ - Win32 Debug
|
||||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
!MESSAGE use the Export Makefile command and run
|
!MESSAGE use the Export Makefile command and run
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
|
@ -13,14 +13,18 @@ CFG=@project_name@ - Win32 Debug Static
|
||||||
!MESSAGE You can specify a configuration when running NMAKE
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static"
|
!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug"
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE Possible choices for configuration are:
|
!MESSAGE Possible choices for configuration are:
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application")
|
!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||||
!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application")
|
!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||||
!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Console Application")
|
!MESSAGE "@project_name@ - Win32 ASCII Debug" (based on "Win32 (x86) Console Application")
|
||||||
!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Console Application")
|
!MESSAGE "@project_name@ - Win32 ASCII Release" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE "@project_name@ - Win64 Debug AMD64" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE "@project_name@ - Win64 Release AMD64" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE "@project_name@ - Win64 Debug IA64" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE "@project_name@ - Win64 Release IA64" (based on "Win32 (x86) Console Application")
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
|
|
||||||
# Begin Project
|
# Begin Project
|
||||||
|
@ -34,99 +38,207 @@ RSC=rc.exe
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
# PROP BASE Output_Dir "Release"
|
# PROP BASE Output_Dir "@bin_rel_dest@"
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
# PROP BASE Intermediate_Dir "Release/@project_name@"
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 0
|
# PROP Use_Debug_Libraries 0
|
||||||
# PROP Output_Dir "Release"
|
# PROP Output_Dir "@bin_rel_dest@"
|
||||||
# PROP Intermediate_Dir "Release"
|
# PROP Intermediate_Dir "Release/@project_name@"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c
|
||||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
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 BASE LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386
|
||||||
# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt"
|
# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" /libpath:"@lib_rel_dest@"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug"
|
!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug"
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
# PROP BASE Output_Dir "Debug"
|
# PROP BASE Output_Dir "@bin_debug_dest@"
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
# PROP BASE Intermediate_Dir "Debug/@project_name@"
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 1
|
# PROP Use_Debug_Libraries 1
|
||||||
# PROP Output_Dir "Debug"
|
# PROP Output_Dir "@bin_debug_dest@"
|
||||||
# PROP Intermediate_Dir "Debug"
|
# PROP Intermediate_Dir "Debug/@project_name@"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c
|
||||||
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c
|
||||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
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 BASE LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no
|
# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no /libpath:"@lib_debug_dest@"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "@project_name@ - Win32 Release Static"
|
!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "@bin_debug_dest@_ASCII"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug_ASCII/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "@bin_debug_dest@_ASCII"
|
||||||
|
# PROP Intermediate_Dir "Debug_ASCII/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c
|
||||||
|
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /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 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no
|
||||||
|
# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no /libpath:"@lib_debug_dest@_ASCII"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Release"
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
# PROP BASE Output_Dir "Release"
|
# PROP BASE Output_Dir "@bin_rel_dest@_ASCII"
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
# PROP BASE Intermediate_Dir "Release_ASCII/@project_name@"
|
||||||
# PROP BASE Ignore_Export_Lib 0
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 0
|
# PROP Use_Debug_Libraries 0
|
||||||
# PROP Output_Dir "Release_static"
|
# PROP Output_Dir "@bin_rel_dest@_ASCII"
|
||||||
# PROP Intermediate_Dir "Release_static"
|
# PROP Intermediate_Dir "Release_ASCII/@project_name@"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c
|
||||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c
|
||||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:I386
|
# ADD BASE LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt"
|
||||||
# ADD LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib /nologo /subsystem:console /machine:I386
|
# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" /libpath:"@lib_rel_dest@_ASCII"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static"
|
!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug AMD64"
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
# PROP BASE Output_Dir "Debug"
|
# PROP BASE Output_Dir "@bin_debug_dest@_AMD64"
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
# PROP BASE Intermediate_Dir "Debug_AMD64/@project_name@"
|
||||||
# PROP BASE Ignore_Export_Lib 0
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 1
|
# PROP Use_Debug_Libraries 1
|
||||||
# PROP Output_Dir "Debug_static"
|
# PROP Output_Dir "@bin_debug_dest@_AMD64"
|
||||||
# PROP Intermediate_Dir "Debug_static"
|
# PROP Intermediate_Dir "Debug_AMD64/@project_name@"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c
|
||||||
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c
|
||||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.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:none /debug /machine:I386 /fixed:no
|
# ADD BASE LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:AMD64 /nodefaultlib:"libcmtd" /fixed:no
|
||||||
# ADD LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.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:none /debug /machine:I386 /fixed:no
|
# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:AMD64 /nodefaultlib:"libcmtd" /fixed:no /libpath:"@lib_debug_dest@_AMD64"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release AMD64"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "@bin_rel_dest@_AMD64"
|
||||||
|
# PROP BASE Intermediate_Dir "Release_AMD64/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "@bin_rel_dest@_AMD64"
|
||||||
|
# PROP Intermediate_Dir "Release_AMD64/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# ADD CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /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 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:AMD64 /nodefaultlib:"libcmt"
|
||||||
|
# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:AMD64 /nodefaultlib:"libcmt" /libpath:"@lib_rel_dest@_AMD64"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug IA64"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "@bin_debug_dest@_IA64"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug_IA64/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "@bin_debug_dest@_IA64"
|
||||||
|
# PROP Intermediate_Dir "Debug_IA64/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /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 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:IA64 /nodefaultlib:"libcmtd" /fixed:no
|
||||||
|
# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:IA64 /nodefaultlib:"libcmtd" /fixed:no /libpath:"@lib_debug_dest@_IA64"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release IA64"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "@bin_rel_dest@_IA64"
|
||||||
|
# PROP BASE Intermediate_Dir "Release_IA64/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "@bin_rel_dest@_IA64"
|
||||||
|
# PROP Intermediate_Dir "Release_IA64/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# ADD CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /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 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:IA64 /nodefaultlib:"libcmt"
|
||||||
|
# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:IA64 /nodefaultlib:"libcmt" /libpath:"@lib_rel_dest@_IA64"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
@ -134,8 +246,12 @@ LINK32=link.exe
|
||||||
|
|
||||||
# Name "@project_name@ - Win32 Release"
|
# Name "@project_name@ - Win32 Release"
|
||||||
# Name "@project_name@ - Win32 Debug"
|
# Name "@project_name@ - Win32 Debug"
|
||||||
# Name "@project_name@ - Win32 Release Static"
|
# Name "@project_name@ - Win32 ASCII Debug"
|
||||||
# Name "@project_name@ - Win32 Debug Static"
|
# Name "@project_name@ - Win32 ASCII Release"
|
||||||
|
# Name "@project_name@ - Win64 Debug AMD64"
|
||||||
|
# Name "@project_name@ - Win64 Release AMD64"
|
||||||
|
# Name "@project_name@ - Win64 Debug IA64"
|
||||||
|
# Name "@project_name@ - Win64 Release IA64"
|
||||||
@SOURCE_FILES@
|
@SOURCE_FILES@
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*-
|
/*-
|
||||||
* See the file LICENSE for redistribution information.
|
* See the file LICENSE for redistribution information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1999-2004
|
* Copyright (c) 1999-2005
|
||||||
* Sleepycat Software. All rights reserved.
|
* Sleepycat Software. All rights reserved.
|
||||||
*
|
*
|
||||||
* $Id: dbkill.cpp,v 11.9 2004/01/28 03:35:52 bostic Exp $
|
* $Id: dbkill.cpp,v 12.1 2005/06/16 20:20:43 bostic Exp $
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Kill -
|
* Kill -
|
||||||
|
|
|
@ -19,6 +19,12 @@ CFG=@project_name@ - Win32 Debug
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "@project_name@ - Win32 ASCII Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "@project_name@ - Win32 ASCII Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "@project_name@ - Win64 Debug AMD64" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "@project_name@ - Win64 Release AMD64" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "@project_name@ - Win64 Debug IA64" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "@project_name@ - Win64 Release IA64" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
|
|
||||||
# Begin Project
|
# Begin Project
|
||||||
|
@ -33,17 +39,17 @@ RSC=rc.exe
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
# PROP BASE Output_Dir "Release"
|
# PROP BASE Output_Dir "@lib_rel_dest@"
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
# PROP BASE Intermediate_Dir "Release/@project_name@"
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 0
|
# PROP Use_Debug_Libraries 0
|
||||||
# PROP Output_Dir "Release"
|
# PROP Output_Dir "@lib_rel_dest@"
|
||||||
# PROP Intermediate_Dir "Release"
|
# PROP Intermediate_Dir "Release/@project_name@"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
|
||||||
# ADD 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 BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
|
@ -52,24 +58,25 @@ BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
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 BASE LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||||
# ADD LINK32 /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll"
|
# ADD LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"@bin_rel_dest@/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" /libpath:"$(OUTDIR)"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug"
|
!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug"
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
# PROP BASE Output_Dir "Debug"
|
# PROP BASE Output_Dir "@lib_debug_dest@"
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
# PROP BASE Intermediate_Dir "Debug/@project_name@"
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 2
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 1
|
# PROP Use_Debug_Libraries 1
|
||||||
# PROP Output_Dir "Debug"
|
# PROP Output_Dir "@lib_debug_dest@"
|
||||||
# PROP Intermediate_Dir "Debug"
|
# PROP Intermediate_Dir "Debug/@project_name@"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
|
||||||
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_CREATE_DLL" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c
|
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c
|
||||||
# SUBTRACT CPP /Fr
|
# SUBTRACT CPP /Fr
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
|
||||||
|
@ -79,8 +86,182 @@ BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
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 BASE LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /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 /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no
|
# ADD LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /export:__db_assert /pdb:none /debug /machine:I386 /out:"@bin_debug_dest@/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no /libpath:"$(OUTDIR)"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "@lib_debug_dest@_ASCII"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug_ASCII/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "@lib_debug_dest@_ASCII"
|
||||||
|
# PROP Intermediate_Dir "Debug_ASCII/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c
|
||||||
|
# SUBTRACT BASE CPP /Fr
|
||||||
|
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c
|
||||||
|
# SUBTRACT CPP /Fr
|
||||||
|
# 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 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"@bin_debug_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no
|
||||||
|
# ADD LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /export:__db_assert /pdb:none /debug /machine:I386 /out:"@bin_debug_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no /libpath:"$(OUTDIR)"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "@lib_rel_dest@_ASCII"
|
||||||
|
# PROP BASE Intermediate_Dir "Release_ASCII/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "@lib_rel_dest@_ASCII"
|
||||||
|
# PROP Intermediate_Dir "Release_ASCII/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c
|
||||||
|
# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c
|
||||||
|
# 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 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"@bin_rel_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll"
|
||||||
|
# ADD LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"@bin_rel_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" /libpath:"$(OUTDIR)"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug AMD64"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "@lib_debug_dest@_AMD64"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug_AMD64/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "@lib_debug_dest@_AMD64"
|
||||||
|
# PROP Intermediate_Dir "Debug_AMD64/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c
|
||||||
|
# SUBTRACT BASE CPP /Fr
|
||||||
|
# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /Wp64 /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 @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /debug /machine:AMD64 /out:"@bin_debug_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no
|
||||||
|
# ADD LINK32 @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /export:__db_assert /debug /machine:AMD64 /out:"@bin_debug_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no /libpath:"$(OUTDIR)"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release AMD64"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "@lib_rel_dest@_AMD64"
|
||||||
|
# PROP BASE Intermediate_Dir "Release_AMD64/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "@lib_rel_dest@_AMD64"
|
||||||
|
# PROP Intermediate_Dir "Release_AMD64/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# ADD CPP /nologo /MD /W3 /EHsc /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# 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 @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:AMD64 /out:"@bin_rel_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll"
|
||||||
|
# ADD LINK32 @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:AMD64 /out:"@bin_rel_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" /libpath:"$(OUTDIR)"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug IA64"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "@lib_debug_dest@_IA64"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug_IA64/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "@lib_debug_dest@_IA64"
|
||||||
|
# PROP Intermediate_Dir "Debug_IA64/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# SUBTRACT BASE CPP /Fr
|
||||||
|
# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# SUBTRACT CPP /Fr
|
||||||
|
# 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 @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /debug /machine:IA64 /out:"@bin_debug_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no
|
||||||
|
# ADD LINK32 @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /export:__db_assert /debug /machine:IA64 /out:"@bin_debug_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no /libpath:"$(OUTDIR)"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release IA64"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "@lib_rel_dest@_IA64"
|
||||||
|
# PROP BASE Intermediate_Dir "Release_IA64/@project_name@"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "@lib_rel_dest@_IA64"
|
||||||
|
# PROP Intermediate_Dir "Release_IA64/@project_name@"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# ADD CPP /nologo /MD /W3 /EHsc /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c
|
||||||
|
# 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 @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:IA64 /out:"@bin_rel_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll"
|
||||||
|
# ADD LINK32 @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:IA64 /out:"@bin_rel_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" /libpath:"$(OUTDIR)"
|
||||||
|
@POST_BUILD@
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
@ -88,6 +269,13 @@ LINK32=link.exe
|
||||||
|
|
||||||
# Name "@project_name@ - Win32 Release"
|
# Name "@project_name@ - Win32 Release"
|
||||||
# Name "@project_name@ - Win32 Debug"
|
# Name "@project_name@ - Win32 Debug"
|
||||||
|
# Name "@project_name@ - Win32 ASCII Debug"
|
||||||
|
# Name "@project_name@ - Win32 ASCII Release"
|
||||||
|
# Name "@project_name@ - Win64 Debug AMD64"
|
||||||
|
# Name "@project_name@ - Win64 Release AMD64"
|
||||||
|
# Name "@project_name@ - Win64 Debug IA64"
|
||||||
|
# Name "@project_name@ - Win64 Release IA64"
|
||||||
@SOURCE_FILES@
|
@SOURCE_FILES@
|
||||||
|
|
||||||
# End Target
|
# End Target
|
||||||
# End Project
|
# End Project
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; $Id: libdb_tcl.def,v 11.7 2002/10/14 23:44:20 mjc Exp $
|
; $Id: libdb_tcl.def,v 12.0 2004/11/17 03:48:15 bostic Exp $
|
||||||
|
|
||||||
DESCRIPTION 'Berkeley DB TCL interface Library'
|
DESCRIPTION 'Berkeley DB TCL interface Library'
|
||||||
EXPORTS
|
EXPORTS
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue