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:
unknown 2005-12-12 12:30:18 +01:00
commit 031ec5d2bd
1049 changed files with 35918 additions and 168064 deletions

View file

@ -133,137 +133,107 @@ autom4te.cache/*
autom4te.cache/output.0
autom4te.cache/requests
autom4te.cache/traces.0
bdb/*.ds?
bdb/*.vcproj
bdb/README
bdb/btree/btree_auto.c
bdb/build_unix/*
bdb/build_vxworks/db.h
bdb/build_vxworks/db_int.h
bdb/build_win32/db.h
bdb/build_win32/db_archive.dsp
bdb/build_win32/db_checkpoint.dsp
bdb/build_win32/db_config.h
bdb/build_win32/db_cxx.h
bdb/build_win32/db_deadlock.dsp
bdb/build_win32/db_dll.dsp
bdb/build_win32/db_dump.dsp
bdb/build_win32/db_int.h
bdb/build_win32/db_java.dsp
bdb/build_win32/db_load.dsp
bdb/build_win32/db_perf.dsp
bdb/build_win32/db_printlog.dsp
bdb/build_win32/db_recover.dsp
bdb/build_win32/db_stat.dsp
bdb/build_win32/db_static.dsp
bdb/build_win32/db_tcl.dsp
bdb/build_win32/db_test.dsp
bdb/build_win32/db_upgrade.dsp
bdb/build_win32/db_verify.dsp
bdb/build_win32/ex_access.dsp
bdb/build_win32/ex_btrec.dsp
bdb/build_win32/ex_env.dsp
bdb/build_win32/ex_lock.dsp
bdb/build_win32/ex_mpool.dsp
bdb/build_win32/ex_tpcb.dsp
bdb/build_win32/excxx_access.dsp
bdb/build_win32/excxx_btrec.dsp
bdb/build_win32/excxx_env.dsp
bdb/build_win32/excxx_lock.dsp
bdb/build_win32/excxx_mpool.dsp
bdb/build_win32/excxx_tpcb.dsp
bdb/build_win32/include.tcl
bdb/build_win32/libdb.def
bdb/build_win32/libdb.rc
bdb/db/crdel_auto.c
bdb/db/db_auto.c
bdb/dbinc_auto/*.*
bdb/dbreg/dbreg_auto.c
bdb/dist/autom4te-2.53.cache/*
bdb/dist/autom4te-2.53.cache/output.0
bdb/dist/autom4te-2.53.cache/requests
bdb/dist/autom4te-2.53.cache/traces.0
bdb/dist/autom4te.cache/*
bdb/dist/autom4te.cache/output.0
bdb/dist/autom4te.cache/requests
bdb/dist/autom4te.cache/traces.0
bdb/dist/config.hin
bdb/dist/configure
bdb/dist/tags
bdb/dist/template/db_server_proc
bdb/dist/template/gen_client_ret
bdb/dist/template/rec_btree
bdb/dist/template/rec_crdel
bdb/dist/template/rec_db
bdb/dist/template/rec_dbreg
bdb/dist/template/rec_fileops
bdb/dist/template/rec_hash
bdb/dist/template/rec_log
bdb/dist/template/rec_qam
bdb/dist/template/rec_txn
bdb/examples_c/ex_apprec/ex_apprec_auto.c
bdb/examples_c/ex_apprec/ex_apprec_auto.h
bdb/examples_c/ex_apprec/ex_apprec_template
bdb/examples_java
bdb/fileops/fileops_auto.c
bdb/hash/hash_auto.c
bdb/include/btree_auto.h
bdb/include/btree_ext.h
bdb/include/clib_ext.h
bdb/include/common_ext.h
bdb/include/crdel_auto.h
bdb/include/db_auto.h
bdb/include/db_ext.h
bdb/include/db_server.h
bdb/include/env_ext.h
bdb/include/gen_client_ext.h
bdb/include/gen_server_ext.h
bdb/include/hash_auto.h
bdb/include/hash_ext.h
bdb/include/lock_ext.h
bdb/include/log_auto.h
bdb/include/log_ext.h
bdb/include/mp_ext.h
bdb/include/mutex_ext.h
bdb/include/os_ext.h
bdb/include/qam_auto.h
bdb/include/qam_ext.h
bdb/include/rpc_client_ext.h
bdb/include/rpc_server_ext.h
bdb/include/tcl_ext.h
bdb/include/txn_auto.h
bdb/include/txn_ext.h
bdb/include/xa_ext.h
bdb/java/src/com/sleepycat/db/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
storage/bdb/*.ds?
storage/bdb/*.vcproj
storage/bdb/README
storage/bdb/btree/btree_auto.c
storage/bdb/build_unix/*
storage/bdb/build_vxworks/db.h
storage/bdb/build_vxworks/db_int.h
storage/bdb/build_win32/db.h
storage/bdb/build_win32/db_archive.dsp
storage/bdb/build_win32/db_checkpoint.dsp
storage/bdb/build_win32/db_config.h
storage/bdb/build_win32/db_cxx.h
storage/bdb/build_win32/db_deadlock.dsp
storage/bdb/build_win32/db_dll.dsp
storage/bdb/build_win32/db_dump.dsp
storage/bdb/build_win32/db_int.h
storage/bdb/build_win32/db_java.dsp
storage/bdb/build_win32/db_load.dsp
storage/bdb/build_win32/db_perf.dsp
storage/bdb/build_win32/db_printlog.dsp
storage/bdb/build_win32/db_recover.dsp
storage/bdb/build_win32/db_stat.dsp
storage/bdb/build_win32/db_static.dsp
storage/bdb/build_win32/db_tcl.dsp
storage/bdb/build_win32/db_test.dsp
storage/bdb/build_win32/db_upgrade.dsp
storage/bdb/build_win32/db_verify.dsp
storage/bdb/build_win32/ex_access.dsp
storage/bdb/build_win32/ex_btrec.dsp
storage/bdb/build_win32/ex_env.dsp
storage/bdb/build_win32/ex_lock.dsp
storage/bdb/build_win32/ex_mpool.dsp
storage/bdb/build_win32/ex_tpcb.dsp
storage/bdb/build_win32/excxx_access.dsp
storage/bdb/build_win32/excxx_btrec.dsp
storage/bdb/build_win32/excxx_env.dsp
storage/bdb/build_win32/excxx_lock.dsp
storage/bdb/build_win32/excxx_mpool.dsp
storage/bdb/build_win32/excxx_tpcb.dsp
storage/bdb/build_win32/include.tcl
storage/bdb/build_win32/libdb.def
storage/bdb/build_win32/libdb.rc
storage/bdb/db/crdel_auto.c
storage/bdb/db/db_auto.c
storage/bdb/dbinc_auto/*.*
storage/bdb/dbreg/dbreg_auto.c
storage/bdb/dist/autom4te-2.53.cache/*
storage/bdb/dist/autom4te-2.53.cache/output.0
storage/bdb/dist/autom4te-2.53.cache/requests
storage/bdb/dist/autom4te-2.53.cache/traces.0
storage/bdb/dist/autom4te.cache/*
storage/bdb/dist/autom4te.cache/output.0
storage/bdb/dist/autom4te.cache/requests
storage/bdb/dist/autom4te.cache/traces.0
storage/bdb/dist/config.hin
storage/bdb/dist/configure
storage/bdb/dist/tags
storage/bdb/dist/template/db_server_proc
storage/bdb/dist/template/gen_client_ret
storage/bdb/dist/template/rec_btree
storage/bdb/dist/template/rec_crdel
storage/bdb/dist/template/rec_db
storage/bdb/dist/template/rec_dbreg
storage/bdb/dist/template/rec_fileops
storage/bdb/dist/template/rec_hash
storage/bdb/dist/template/rec_log
storage/bdb/dist/template/rec_qam
storage/bdb/dist/template/rec_txn
storage/bdb/fileops/fileops_auto.c
storage/bdb/hash/hash_auto.c
storage/bdb/include/btree_auto.h
storage/bdb/include/btree_ext.h
storage/bdb/include/clib_ext.h
storage/bdb/include/common_ext.h
storage/bdb/include/crdel_auto.h
storage/bdb/include/db_auto.h
storage/bdb/include/db_ext.h
storage/bdb/include/db_server.h
storage/bdb/include/env_ext.h
storage/bdb/include/gen_client_ext.h
storage/bdb/include/gen_server_ext.h
storage/bdb/include/hash_auto.h
storage/bdb/include/hash_ext.h
storage/bdb/include/lock_ext.h
storage/bdb/include/log_auto.h
storage/bdb/include/log_ext.h
storage/bdb/include/mp_ext.h
storage/bdb/include/mutex_ext.h
storage/bdb/include/os_ext.h
storage/bdb/include/qam_auto.h
storage/bdb/include/qam_ext.h
storage/bdb/include/rpc_client_ext.h
storage/bdb/include/rpc_server_ext.h
storage/bdb/include/tcl_ext.h
storage/bdb/include/txn_auto.h
storage/bdb/include/txn_ext.h
storage/bdb/include/xa_ext.h
storage/bdb/log/log_auto.c
storage/bdb/qam/qam_auto.c
storage/bdb/txn/txn_auto.c
storage/bdb/txn/txn_autop.c
binary/*
bkpull.log
bkpull.log*
@ -1688,3 +1658,4 @@ vio/viotest-sslconnect.cpp
vio/viotest.cpp
zlib/*.ds?
zlib/*.vcproj
client/mysqlslap

View file

@ -2,7 +2,7 @@
#shift
FROM=$USER@mysql.com
INTERNALS=internals@lists.mysql.com
COMMITS=commits@lists.mysql.com
DOCS=docs-commit@mysql.com
LIMIT=10000
VERSION="5.1"
@ -61,14 +61,14 @@ EOF
) | /usr/sbin/sendmail -t
#++
# internals@ mail
# commits@ mail
#--
echo "Notifying internals list at $INTERNALS"
echo "Notifying commits list at $COMMITS"
(
cat <<EOF
List-ID: <bk.mysql-$VERSION>
From: $FROM
To: $INTERNALS
To: $COMMITS
Subject: bk commit into $VERSION tree ($CHANGESET)$BS
X-CSetKey: <$CSETKEY>
$BH

View file

@ -120,6 +120,28 @@
<Filter
Name="Source Files"
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
RelativePath="btree\bt_compare.c">
<FileConfiguration
@ -500,6 +522,25 @@
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="db\db.c">
<FileConfiguration
@ -595,6 +636,9 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\common\db_clock.c">
</File>
<File
RelativePath="db\db_conv.c">
<FileConfiguration
@ -994,25 +1038,6 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</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
RelativePath="db\db_setid.c">
<FileConfiguration
@ -1051,6 +1076,25 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</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
RelativePath="db\db_stati.c">
<FileConfiguration
@ -1279,6 +1323,9 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\env\env_failchk.c">
</File>
<File
RelativePath="env\env_file.c">
<FileConfiguration
@ -1374,6 +1421,9 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\env\env_register.c">
</File>
<File
RelativePath="env\env_stat.c">
<FileConfiguration
@ -1811,6 +1861,9 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\lock\lock_failchk.c">
</File>
<File
RelativePath="lock\lock_id.c">
<FileConfiguration
@ -1831,7 +1884,7 @@
</FileConfiguration>
</File>
<File
RelativePath="lock\lock_method.c">
RelativePath="lock\lock_list.c">
<FileConfiguration
Name="Max|Win32">
<Tool
@ -1850,7 +1903,7 @@
</FileConfiguration>
</File>
<File
RelativePath="lock\lock_list.c">
RelativePath="lock\lock_method.c">
<FileConfiguration
Name="Max|Win32">
<Tool
@ -2001,6 +2054,9 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\log\log_debug.c">
</File>
<File
RelativePath="log\log_get.c">
<FileConfiguration
@ -2324,6 +2380,37 @@
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=".\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
RelativePath="mutex\mut_tas.c">
<FileConfiguration
@ -2362,25 +2449,6 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</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
RelativePath="os_win32\os_abs.c">
<FileConfiguration
@ -2514,6 +2582,9 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\os_win32\os_flock.c">
</File>
<File
RelativePath="os_win32\os_fsync.c">
<FileConfiguration
@ -3103,6 +3174,12 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\rep\rep_elect.c">
</File>
<File
RelativePath=".\rep\rep_log.c">
</File>
<File
RelativePath="rep\rep_method.c">
<FileConfiguration
@ -3179,6 +3256,9 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\rep\rep_stub.c">
</File>
<File
RelativePath="rep\rep_util.c">
<FileConfiguration
@ -3198,6 +3278,47 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</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
RelativePath="hmac\sha1.c">
<FileConfiguration
@ -3274,6 +3395,12 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath=".\txn\txn_chkpt.c">
</File>
<File
RelativePath=".\txn\txn_failchk.c">
</File>
<File
RelativePath="txn\txn_method.c">
<FileConfiguration
@ -3483,101 +3610,6 @@
PreprocessorDefinitions=""/>
</FileConfiguration>
</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
Name="Header Files"

View file

@ -341,6 +341,7 @@ long SSL_CTX_sess_set_cache_size(SSL_CTX*, long);
long SSL_CTX_set_tmp_dh(SSL_CTX*, DH*);
void OpenSSL_add_all_algorithms(void);
void SSL_library_init();
void SSLeay_add_ssl_algorithms(void);

View file

@ -648,6 +648,10 @@ void OpenSSL_add_all_algorithms() // compatibility only
{}
void SSL_library_init() // compatibility only
{}
DH* DH_new(void)
{
DH* dh = new (ys) DH;

View file

@ -117,6 +117,9 @@ typedef unsigned long long my_ulonglong;
#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 {
struct st_mysql_rows *next; /* list of rows */
MYSQL_ROW data;

View 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 ;|

View file

@ -2317,7 +2317,7 @@ CREATE TABLE t2(c2 char(2)) default charset = ujis;
INSERT INTO t1 VALUES(_ujis 0xA4A2);
CREATE PROCEDURE sp1()
BEGIN
DECLARE a CHAR(1);
DECLARE a CHAR(2) CHARSET ujis;
DECLARE cur1 CURSOR FOR SELECT c1 FROM t1;
OPEN cur1;
FETCH cur1 INTO a;

View file

@ -1,3 +1,4 @@
drop database if exists mysqltest1;
create schema foo;
show create schema foo;
Database Create Database

View file

@ -1,6 +1,7 @@
drop table if exists t1,t2;
drop table if exists t1aa,t2aa;
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.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
flush privileges;

View file

@ -10,5 +10,5 @@ user()
#
show processlist;
Id User Host db Command Time State Info
# root # test Sleep # NULL
# root # test Query # NULL show processlist
<id> root <host> test <command> <time> <state> <info>
<id> root <host> test <command> <time> <state> <info>

View file

@ -25,6 +25,7 @@ count(*)
select count(*) from t2;
count(*)
0
drop procedure if exists p1;
create procedure p1()
begin
declare done integer default 0;

View 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;

View file

@ -1,3 +1,5 @@
drop procedure if exists p1|
drop procedure if exists p2|
create procedure p1()
begin
prepare stmt from "select 1";

View file

@ -124,7 +124,7 @@ begin
declare x int;
set x = val+3;
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
begin
declare x int;
@ -768,7 +768,7 @@ BEGIN
OPTIMIZE TABLE t1;
RETURN 1;
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|
CREATE FUNCTION bug12995() RETURNS INT
BEGIN
@ -981,6 +981,8 @@ END |
drop table t1|
drop function bug_13627_f|
drop function if exists bug12329;
Warnings:
Note 1305 FUNCTION bug12329 does not exist
create table t1 as select 1 a;
create table t2 as select 1 a;
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
drop database mysqltest2;
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

File diff suppressed because it is too large Load diff

View file

@ -248,13 +248,13 @@ return i+1|
call sub1("sub1a", (select 7))|
call sub1("sub1b", (select max(i) from t2))|
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 sub2("sub2")|
select * from t1|
id data
sub1a 7
sub1b 3
sub1c 1
sub1d 1
sub2 6
select sub3((select max(i) from t2))|
@ -2686,7 +2686,7 @@ call bug8937()|
s x y z
16 3 1 6
a
3.2000
3.2
drop procedure bug8937|
delete from t1|
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')|
bug9775('a') bug9775('b') bug9775('c')
a b
Warnings:
Warning 1265 Data truncated for column 'bug9775('c')' at row 1
drop function bug9775|
create function bug9775(v1 int) returns enum('a','b') return v1|
select bug9775(1),bug9775(2),bug9775(3)|
bug9775(1) bug9775(2) bug9775(3)
a b
Warnings:
Warning 1265 Data truncated for column 'bug9775(3)' at row 1
drop function bug9775|
create function bug9775(v1 char(1)) returns set('a','b') return v1|
select 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|
create function bug9775(v1 int) returns set('a','b') return v1|
select bug9775(1),bug9775(2),bug9775(3),bug9775(4)|
bug9775(1) bug9775(2) bug9775(3) bug9775(4)
a b a,b
Warnings:
Warning 1265 Data truncated for column 'bug9775(4)' at row 1
drop function bug9775|
drop function if exists bug8861|
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('12345678901234567')|
Warnings:
Warning 1265 Data truncated for column 'id' at row 1
Warning 1265 Data truncated for column 'id' at row 2
Warning 1265 Data truncated for column 'x' at row 1
call bug9004_2('12345678901234567890')|
Warnings:
Warning 1265 Data truncated for column 'id' at row 1
Warning 1265 Data truncated for column 'id' at row 2
Warning 1265 Data truncated for column 'x' at row 1
delete from t1|
drop procedure bug9004_1|
drop procedure bug9004_2|
@ -3527,14 +3534,15 @@ end|
call bug12589_1()|
Table Create Table
tm1 CREATE TEMPORARY TABLE `tm1` (
`spv1` decimal(1,0) unsigned default NULL
`spv1` decimal(3,3) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
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()|
Table Create Table
tm1 CREATE TEMPORARY TABLE `tm1` (
`spv1` decimal(6,3) unsigned default NULL
`spv1` decimal(6,3) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
call bug12589_3()|
Table Create Table
@ -4016,34 +4024,37 @@ create procedure bug14643_1()
begin
declare continue handler for sqlexception select 'boo' as 'Handler';
begin
declare v int default x;
declare v int default undefined_var;
if v = 1 then
select 1;
else
select 2;
select v, isnull(v);
end if;
end;
end|
create procedure bug14643_2()
begin
declare continue handler for sqlexception select 'boo' as 'Handler';
case x
case undefined_var
when 1 then
select 1;
else
select 2;
end case;
select undefined_var;
end|
call bug14643_1()|
Handler
boo
2
2
v isnull(v)
NULL 1
call bug14643_2()|
Handler
boo
2
2
Handler
boo
drop procedure bug14643_1|
drop procedure bug14643_2|
drop procedure if exists bug14304|
@ -4100,8 +4111,6 @@ x
4711
drop procedure bug14376|
drop procedure if exists p1|
Warnings:
Note 1305 PROCEDURE p1 does not exist
drop table if exists t1|
create table t1 (a varchar(255))|
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 takes precedence over table column in cursors
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;

View file

@ -1,5 +1,4 @@
using_big_test
0
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (id INTEGER);
CREATE TABLE t2 (id INTEGER);
INSERT INTO t1 (id) VALUES (1), (1), (1),(1);
@ -40,19 +39,19 @@ AVG(DISTINCT id)
512.5000
SELECT SUM(DISTINCT id)/COUNT(DISTINCT id) FROM t1 GROUP BY id % 13;
SUM(DISTINCT id)/COUNT(DISTINCT id)
513.50000
508.00000
509.00000
510.00000
511.00000
512.00000
513.00000
514.00000
515.00000
516.00000
517.00000
511.50000
512.50000
513.5000
508.0000
509.0000
510.0000
511.0000
512.0000
513.0000
514.0000
515.0000
516.0000
517.0000
511.5000
512.5000
INSERT INTO t1 SELECT id+1024 FROM t1;
INSERT INTO t1 SELECT id+2048 FROM t1;
INSERT INTO t1 SELECT id+4096 FROM t1;

View file

@ -114,3 +114,26 @@ drop table t1;
select hex(cast(0x10 as binary(2)));
hex(cast(0x10 as binary(2)))
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

View file

@ -1,11 +1,26 @@
drop procedure if exists sp1;
create procedure sp1 () begin
declare v1, v2, v3, v4 decimal(16,12); declare v5 int;
set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = 0;
while v5 < 100000 do
set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1;
end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;//
CREATE PROCEDURE sp1()
BEGIN
DECLARE v1, v2, v3, v4 DECIMAL(28,12);
DECLARE v3_2, v4_2 DECIMAL(28, 12);
DECLARE counter INT;
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()//
v1 v2 v3 * 0.000000000001 v4 * 0.000000000001
1.000000100000 1.999999900000 1.000000100000 1.999999900000
v1 v2 v3 v3_2 v4 v4_2
1.000000100000 1.999999900000 1000000100000.000000000000 1.000000100000 1999999900000.000000000000 1.999999900000
drop procedure sp1;

View file

@ -2383,20 +2383,25 @@ CREATE TABLE t1(id INT);
CREATE VIEW v1 AS SELECT id FROM t1;
OPTIMIZE TABLE v1;
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;
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;
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;
OPTIMIZE TABLE v1;
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 1146 Table 'test.t1' doesn't exist
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
Error 1347 'test.v1' is not BASE TABLE
DROP VIEW v1;
create definer = current_user() sql security invoker view v1 as select 1;
show create view v1;

View file

@ -52,5 +52,6 @@ unlock tables;
connection con1;
reap;
drop table t5;
--system rm $MYSQL_TEST_DIR/var/tmp/t?.*
# End of 4.1 tests

View file

@ -1170,7 +1170,7 @@ INSERT INTO t1 VALUES(_ujis 0xA4A2);
DELIMITER |;
CREATE PROCEDURE sp1()
BEGIN
DECLARE a CHAR(1);
DECLARE a CHAR(2) CHARSET ujis;
DECLARE cur1 CURSOR FOR SELECT c1 FROM t1;
OPEN cur1;
FETCH cur1 INTO a;

View file

@ -1,6 +1,12 @@
#
# 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;
show create schema foo;

View file

@ -10,6 +10,7 @@
drop table if exists t1,t2;
drop table if exists t1aa,t2aa;
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.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';

View file

@ -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, );
--replace_column 1 #
select user();
--replace_column 1 # 6 # 3 #
--replace_column 1 <id> 3 <host> 5 <command> 6 <time> 7 <state> 8 <info>
show processlist;
connection default;

View file

@ -52,6 +52,9 @@ while ($1)
--enable_query_log
select count(*) from t1;
select count(*) from t2;
--disable_warnings
drop procedure if exists p1;
--enable_warnings
delimiter |;
create procedure p1()
begin

View 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;

View file

@ -1,4 +1,10 @@
delimiter |;
--disable_warnings
drop procedure if exists p1|
drop procedure if exists p2|
--enable_warnings
######################################################################
# Test Dynamic SQL in stored procedures. #############################
######################################################################

View file

@ -1095,7 +1095,7 @@ delimiter |;
--disable_warnings
DROP FUNCTION IF EXISTS bug12953|
--enable_warnings
--error ER_SP_BADSTATEMENT
--error ER_SP_NO_RETSET
CREATE FUNCTION bug12953() RETURNS INT
BEGIN
OPTIMIZE TABLE t1;
@ -1410,7 +1410,6 @@ delimiter ;|
# 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
--disable_warnings
drop function if exists bug12329;
--enable_warnings
create table t1 as select 1 a;
@ -1518,6 +1517,44 @@ show procedure status;
drop database mysqltest2;
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
#

1273
mysql-test/t/sp-vars.test Normal file

File diff suppressed because it is too large Load diff

View file

@ -13,6 +13,8 @@
# Tests that require multiple connections, except security/privilege tests,
# go to sp-thread.
# 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;
@ -365,6 +367,7 @@ create function sub3(i int) returns int
call sub1("sub1a", (select 7))|
call sub1("sub1b", (select max(i) from t2))|
--error ER_OPERAND_COLUMNS
call sub1("sub1c", (select i,d from t2 limit 1))|
call sub1("sub1d", (select 1 from (select 1) a))|
call sub2("sub2")|
@ -4795,12 +4798,12 @@ begin
declare continue handler for sqlexception select 'boo' as 'Handler';
begin
declare v int default x;
declare v int default undefined_var;
if v = 1 then
select 1;
else
select 2;
select v, isnull(v);
end if;
end;
end|
@ -4809,12 +4812,14 @@ create procedure bug14643_2()
begin
declare continue handler for sqlexception select 'boo' as 'Handler';
case x
case undefined_var
when 1 then
select 1;
else
select 2;
end case;
select undefined_var;
end|
call bug14643_1()|
@ -4908,8 +4913,10 @@ drop procedure bug14376|
# variable declarations. In MySQL 5.0 it's vice versa.
#
--disable_warnings
drop procedure if exists p1|
drop table if exists t1|
--enable_warnings
create table t1 (a varchar(255))|
insert into t1 (a) values ("a - table column")|
create procedure p1(a varchar(255))
@ -4944,6 +4951,82 @@ begin
end;
end|
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

View file

@ -68,3 +68,27 @@ drop table t1;
# check that cast appends trailing zeros
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

View file

@ -12,12 +12,31 @@ drop procedure if exists sp1;
delimiter //;
#
create procedure sp1 () begin
declare v1, v2, v3, v4 decimal(16,12); declare v5 int;
set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = 0;
while v5 < 100000 do
set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1;
end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;//
CREATE PROCEDURE sp1()
BEGIN
DECLARE v1, v2, v3, v4 DECIMAL(28,12);
DECLARE v3_2, v4_2 DECIMAL(28, 12);
DECLARE counter INT;
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()//
#-- should return

View file

@ -5859,44 +5859,52 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
uint copy_length;
/* See the comment for Field_long::store(long long) */
DBUG_ASSERT(table->in_use == current_thd);
/* Convert character set if necessary */
if (String::needs_conversion(length, cs, field_charset, &not_used))
{
{
uint conv_errors;
tmpstr.copy(from, length, cs, field_charset, &conv_errors);
from= tmpstr.ptr();
length= tmpstr.length();
length= tmpstr.length();
if (conv_errors)
error= 2;
}
/*
Make sure we don't break a multibyte sequence
as well as don't copy a malformed data.
*/
/* Make sure we don't break a multibyte sequence or copy malformed data. */
copy_length= field_charset->cset->well_formed_len(field_charset,
from,from+length,
field_length/
field_charset->mbmaxlen,
&well_formed_error);
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_length-copy_length,
field_length-copy_length,
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)
{ // Check if we loosed some info
const char *end=from+length;
from+= copy_length;
from+= field_charset->cset->scan(field_charset, from, end,
MY_SEQ_SPACES);
if (from != end)
{
if (binary())
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)
{
@ -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 &&
!error_code)
{
const char *end= from + length;
from+= copy_length;
from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES);
/* If we lost only spaces then produce a NOTE, not a WARNING */
if (from == end)
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
if (!binary())
{
const char *end= from + length;
from+= copy_length;
from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES);
/* 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;
}
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;
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 type;

View file

@ -134,7 +134,19 @@ public:
null_bit == field->null_bit);
}
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; }
/*
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 sort_length() const { return 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,
uint32 max_length, uint32 decimals,
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);
};

View file

@ -432,7 +432,7 @@ bool federated_db_init()
DBUG_ENTER("federated_db_init");
if (pthread_mutex_init(&federated_mutex, MY_MUTEX_INIT_FAST))
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))
{
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_COMMA);
}
query.length(query.length()- FEDERATED_COMMA_LEN);
query.length(query.length()- (FEDERATED_COMMA_LEN - 1));
query.append(FEDERATED_FROM);
query.append(FEDERATED_BTICK);

View file

@ -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():
rsize(0), name(0), orig_name(0), name_length(0), fixed(0),
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);
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);
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);
Item *it= this_item();
String *res= it->val_str(sp);
null_value= it->null_value;
if (!res)
return NULL;
@ -854,11 +870,12 @@ String *Item_splocal::val_str(String *sp)
str_value.set(res->ptr(), res->length(), res->charset());
else
res->mark_as_const();
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);
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 it->is_null();
return this_item()->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_splocal::this_item()
{
DBUG_ASSERT(owner == thd->spcont->owner);
return thd->spcont->get_item(m_offset);
DBUG_ASSERT(m_sp == m_thd->spcont->sp);
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_splocal::this_item_addr(THD *thd, Item **addr)
Item_splocal::this_item_addr(THD *thd, Item **)
{
DBUG_ASSERT(owner == thd->spcont->owner);
return thd->spcont->get_item_addr(m_offset);
}
DBUG_ASSERT(m_sp == thd->spcont->sp);
Item *
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;
return thd->spcont->get_item_addr(m_var_idx);
}
@ -934,7 +940,53 @@ void Item_splocal::print(String *str)
str->reserve(m_name.length+8);
str->append(m_name.str, m_name.length);
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)
{
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);
return set_field_to_null_with_conversions(field, no_conversions);
}
/* NOTE: If null_value == FALSE, "result" must be not NULL. */
field->set_notnull();
error=field->store(result->ptr(),result->length(),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.
*/
(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;
triggers= table->triggers;
}

View file

@ -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);
@ -341,8 +383,6 @@ public:
{ return (void*) sql_alloc((uint) size); }
static void *operator new(size_t size, MEM_ROOT *mem_root)
{ 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, MEM_ROOT *mem_root) {}
@ -671,13 +711,13 @@ public:
current value and pointer to current Item otherwise.
*/
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
current value and pointer passed via parameter otherwise.
*/
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
virtual uint cols() { return 1; }
@ -706,21 +746,32 @@ public:
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:
#ifndef DBUG_OFF
@ -728,11 +779,74 @@ public:
Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling.
*/
sp_head *owner;
sp_head *m_sp;
#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
statement itself is in sp_instr_stmt::m_query).
@ -745,78 +859,94 @@ public:
*/
uint pos_in_query;
Item_splocal(LEX_STRING name, uint offset, uint pos_in_q=0)
: m_offset(offset), m_name(name), thd(0), pos_in_query(pos_in_q)
{
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;
}
Item_splocal(const LEX_STRING &sp_var_name, uint sp_var_idx,
enum_field_types sp_var_type, uint pos_in_q= 0);
bool is_splocal() { return 1; } /* Needed for error checking */
Item *this_item();
const Item *this_item() const;
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 make_field(Send_field *field)
{
Item *it= this_item();
public:
inline const LEX_STRING *my_name() const;
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 uint get_var_idx() const;
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);
}
inline enum Type type() const;
inline Item_result result_type() const;
};
/*****************************************************************************
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).
@ -843,7 +973,6 @@ public:
}
bool fix_fields(THD *, Item **);
void cleanup();
enum Type type() const;
double val_real();

View file

@ -4720,7 +4720,7 @@ Item_func_sp::sp_result_field(void) const
dummy_table->s->table_name.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);
}
@ -4733,17 +4733,17 @@ Item_func_sp::sp_result_field(void) const
1 value = NULL or error
*/
int
bool
Item_func_sp::execute(Field **flp)
{
Item *it;
THD *thd= current_thd;
Field *f;
if (execute(&it))
{
null_value= 1;
context->process_error(current_thd);
return 1;
}
/*
Get field in virtual tmp table to store result. Create the field if
invoked first time.
*/
if (!(f= *flp))
{
*flp= f= sp_result_field();
@ -4752,20 +4752,33 @@ Item_func_sp::execute(Field **flp)
f->null_ptr= (uchar *)&null_value;
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
Item_func_sp::execute(Item **itp)
bool
Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
{
DBUG_ENTER("Item_func_sp::execute");
THD *thd= current_thd;
int res= -1;
bool err_status= TRUE;
Sub_statement_state statement_state;
Security_context *save_security_ctx= thd->security_ctx, *save_ctx_func;
DBUG_ENTER("Item_func_sp::execute_impl");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (context->security_ctx)
{
@ -4782,7 +4795,7 @@ Item_func_sp::execute(Item **itp)
function call into binlog.
*/
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);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@ -4792,7 +4805,7 @@ error:
#else
error:
#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");
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)
res= Item_func::tmp_table_field(t_arg);

View file

@ -1374,8 +1374,8 @@ private:
Field *result_field;
char result_buf[64];
int execute(Item **itp);
int execute(Field **flp);
bool execute(Field **flp);
bool execute_impl(THD *thd, Field *return_value_fld);
Field *sp_result_field(void) const;
public:

View file

@ -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);
int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
KEY_CACHE *dst_cache);
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list);
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);
Field *
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
const char *name, const char *item_name,
const char *table_name, const char *db_name,
uint length, Item **ref,
bool check_grants_table, bool check_grants_view,
bool allow_rowid,
const char *name, uint length,
const char *item_name, const char *db_name,
const char *table_name, Item **ref,
bool check_privileges, bool allow_rowid,
uint *cached_field_index_ptr,
bool register_tree_change, TABLE_LIST **actual_table);
Field *
find_field_in_table(THD *thd, TABLE *table, const char *name,
uint length, bool check_grants, bool allow_rowid,
uint *cached_field_index_ptr,
Security_context *sctx);
find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
bool allow_rowid, uint *cached_field_index_ptr);
Field *
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);
void store_position_for_column(const char *name);
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,
TABLE_LIST *right_op);
bool push_new_name_resolution_context(THD *thd,
TABLE_LIST *left_op,
TABLE_LIST *right_op);
void add_join_on(TABLE_LIST *b,Item *expr);
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields);
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,
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"
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);

View file

@ -4697,12 +4697,12 @@ Disable with --skip-bdb (will save memory).",
{"bdb-lock-detect", OPT_BDB_LOCK,
"Berkeley lock detect (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"bdb-logdir", OPT_BDB_LOG, "Berkeley DB log file directory.",
(gptr*) &berkeley_logdir, (gptr*) &berkeley_logdir, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"bdb-log-direct", OPT_BDB_LOG_DIRECT,
"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},
{"bdb-logdir", OPT_BDB_LOG, "Berkeley DB log file directory.",
(gptr*) &berkeley_logdir, (gptr*) &berkeley_logdir, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"bdb-no-recover", OPT_BDB_NO_RECOVER,
"Don't try to recover Berkeley DB tables on start.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},

View file

@ -791,9 +791,9 @@ struct show_var_st init_vars[]= {
{sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
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_use_mmap.name, (char*) &sys_myisam_use_mmap, SHOW_SYS},
#ifdef __NT__
{"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},
#endif
{"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_open_cache", (char*) &table_cache_size, SHOW_LONG},
{sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
{sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
#ifdef HAVE_THR_SETCONCURRENCY

View file

@ -4590,7 +4590,7 @@ ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 21000
nla "De gebruikte SELECT commando's hebben een verschillend aantal kolommen"
eng "The used SELECT statements have a different number of columns"
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"
por "Os comandos SELECT usados têm diferente número de colunas"
rus "éÓÐÏÌØÚÏ×ÁÎÎÙÅ ÏÐÅÒÁÔÏÒÙ ×ÙÂÏÒËÉ (SELECT) ÄÁÀÔ ÒÁÚÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ×"
@ -5271,7 +5271,7 @@ ER_VIEW_SELECT_TMPTABLE
ukr "View SELECT ×ÉËÏÒÉÓÔÏ×Õ¤ ÔÉÍÞÁÓÏ×Õ ÔÁÂÌÉÃÀ '%-.64s'"
ER_VIEW_WRONG_LIST
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 ÉÍÅÀÔ ÒÁÚÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ×"
ukr "View SELECT ¦ ÐÅÒÅÌ¦Ë ÓÔÏ×ÂÃ¦× view ÍÁÀÔØ Ò¦ÚÎÕ Ë¦ÌØ˦ÓÔØ ÓËÏ×Âæ×"
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"
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"
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
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)"
@ -5593,10 +5593,15 @@ ER_SP_BAD_VAR_SHADOW 42000
ger "Variable '%-.64s' muss mit `...` geschützt oder aber umbenannt werden"
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."
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
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
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
eng "%s PARTITIONING requires definition of VALUES %s for each partition"
swe "%s PARTITIONering kräver definition av VALUES %s för varje partition"

107
sql/sp.cc
View file

@ -468,7 +468,7 @@ sp_returns_type(THD *thd, String &result, sp_head *sp)
bzero((char*) &share, sizeof(share));
table.in_use= thd;
table.s = &share;
field= sp->make_field(0, 0, &table);
field= sp->create_result_field(0, 0, &table);
field->sql_type(result);
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
the body of the first routine (i.e. *start)
will be executed in non-prelocked mode.
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
NOTE
If some function is missing this won't be reported here.
Instead this fact will be discovered during query execution.
RETURN VALUE
TRUE - some tables were added
FALSE - no tables were added.
0 - success
non-0 - failure
*/
static bool
static int
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
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;
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.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)
sp_cache_insert(&thd->sp_func_cache, sp);
else
sp_cache_insert(&thd->sp_proc_cache, sp);
case SP_OK:
{
if (type == TYPE_ENUM_FUNCTION)
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)
@ -1495,12 +1535,15 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
if (!(first && first_no_prelock))
{
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;
}
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
first_no_prelock - If true, don't add tables or cache routines used by
the body of the first routine (i.e. *start)
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
RETURN VALUE
TRUE - some tables were added
FALSE - no tables were added.
0 - success
non-0 - failure
*/
bool
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
int
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,
(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
lex - LEX representing statement
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)
{
Sroutine_hash_entry **last_cached_routine_ptr=
(Sroutine_hash_entry **)lex->sroutines_list.next;
sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list);
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
*last_cached_routine_ptr, FALSE);
return sp_cache_routines_and_add_tables_aux(thd, lex,
*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
lex - LEX respresenting statement
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,
Table_triggers_list *triggers)
{
int ret= 0;
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key))
{
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,
*last_cached_routine_ptr,
FALSE);
ret= sp_cache_routines_and_add_tables_aux(thd, lex,
*last_cached_routine_ptr,
FALSE, NULL);
}
return ret;
}

View file

@ -84,11 +84,11 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
sp_name *rt, char rt_type);
void sp_remove_not_own_routines(LEX *lex);
void sp_update_sp_used_routines(HASH *dst, HASH *src);
bool sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
bool first_no_prelock);
void sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
LEX *aux_lex);
void sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
bool first_no_prelock, bool *tabs_changed);
int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
LEX *aux_lex);
int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
Table_triggers_list *triggers);
extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,9 @@
Item_result
sp_map_result_type(enum enum_field_types type);
Item::Type
sp_map_item_type(enum enum_field_types type);
uint
sp_get_flags_for_command(LEX *lex);
@ -123,12 +126,9 @@ public:
/* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
int m_type;
uint m_flags; // Boolean attributes of a stored routine
enum enum_field_types m_returns; // For FUNCTIONs only
Field::geometry_type m_geom_returns;
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
create_field m_return_field_def; /* This is used for FUNCTIONs only. */
const uchar *m_tmp_query; // Temporary pointer to sub query string
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
st_sp_chistics *m_chistics;
@ -202,9 +202,6 @@ public:
void
init_strings(THD *thd, LEX *lex, sp_name *name);
TYPELIB *
create_typelib(List<String> *src);
int
create(THD *thd);
@ -214,10 +211,10 @@ public:
void
destroy();
int
execute_function(THD *thd, Item **args, uint argcount, Item **resp);
bool
execute_function(THD *thd, Item **args, uint argcount, Field *return_fld);
int
bool
execute_procedure(THD *thd, List<Item> *args);
int
@ -278,7 +275,12 @@ public:
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,
st_sp_chistics *chistics, ulong sql_mode);
@ -363,7 +365,7 @@ private:
*/
HASH m_sptabs;
int
bool
execute(THD *thd);
/*
@ -1074,6 +1076,31 @@ private:
}; // 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
bool
sp_change_security_context(THD *thd, sp_head *sp,
@ -1086,8 +1113,10 @@ TABLE_LIST *
sp_add_to_query_tables(THD *thd, LEX *lex,
const char *db, const char *name,
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,
Item *reuse, bool use_callers_arena);
bool
sp_eval_expr(THD *thd, Field *result_field, Item *expr_item);
#endif /* _SP_HEAD_H_ */

View file

@ -51,21 +51,26 @@ sp_cond_check(LEX_STRING *sqlstate)
}
sp_pcontext::sp_pcontext(sp_pcontext *prev)
: Sql_alloc(), m_psubsize(0), m_csubsize(0), m_hsubsize(0),
m_handlers(0), m_parent(prev), m_pboundary(0)
:Sql_alloc(), m_total_pvars(0), m_csubsize(0), m_hsubsize(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_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_cursor, sizeof(LEX_STRING), 16, 8));
VOID(my_init_dynamic_array(&m_handler, sizeof(sp_cond_type_t *), 16, 8));
m_label.empty();
m_children.empty();
if (!prev)
{
m_poffset= m_coffset= 0;
m_num_case_exprs= 0;
}
else
{
m_poffset= prev->current_pvars();
m_poffset= prev->m_poffset + prev->m_total_pvars;
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_label.empty();
delete_dynamic(&m_pvar);
delete_dynamic(&m_case_expr_id_lst);
delete_dynamic(&m_cond);
delete_dynamic(&m_cursor);
delete_dynamic(&m_handler);
@ -99,16 +105,19 @@ sp_pcontext::push_context()
sp_pcontext *
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)
m_parent->m_psubsize= submax;
submax= max_handlers();
uint submax= max_handlers();
if (submax > m_parent->m_hsubsize)
m_parent->m_hsubsize= submax;
submax= max_cursors();
if (submax > m_parent->m_csubsize)
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;
}
@ -191,26 +200,29 @@ sp_pcontext::find_pvar(uint offset)
return NULL; // index out of bounds
}
void
sp_pvar_t *
sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
sp_param_mode_t mode)
{
sp_pvar_t *p= (sp_pvar_t *)sql_alloc(sizeof(sp_pvar_t));
if (p)
{
if (m_pvar.elements == m_psubsize)
m_psubsize+= 1;
p->name.str= name->str;
p->name.length= name->length;
p->type= type;
p->mode= mode;
p->offset= current_pvars();
p->dflt= NULL;
insert_dynamic(&m_pvar, (gptr)&p);
}
if (!p)
return NULL;
++m_total_pvars;
p->name.str= name->str;
p->name.length= name->length;
p->type= type;
p->mode= mode;
p->offset= current_pvars();
p->dflt= NULL;
insert_dynamic(&m_pvar, (gptr)&p);
return p;
}
sp_label_t *
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;
}
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.
This is only used for debugging.

View file

@ -34,8 +34,16 @@ typedef struct sp_pvar
LEX_STRING name;
enum enum_field_types type;
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;
create_field field_def;
} sp_pvar_t;
@ -114,9 +122,9 @@ class sp_pcontext : public Sql_alloc
//
inline uint
max_pvars()
total_pvars()
{
return m_psubsize + m_pvar.elements;
return m_total_pvars;
}
inline uint
@ -155,16 +163,15 @@ class sp_pcontext : public Sql_alloc
p->dflt= it;
}
void
sp_pvar_t *
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
pop_pvar(uint num = 1)
{
while (num--)
pop_dynamic(&m_pvar);
}
/*
Retrieve definitions of fields from the current context and its
children.
*/
void
retrieve_field_definitions(List<create_field> *field_def_lst);
// Find by name
sp_pvar_t *
@ -175,7 +182,7 @@ class sp_pcontext : public Sql_alloc
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.
*/
inline void
@ -184,6 +191,45 @@ class sp_pcontext : public Sql_alloc
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
//
@ -280,8 +326,18 @@ class sp_pcontext : public Sql_alloc
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
uint m_psubsize;
uint m_csubsize;
uint m_hsubsize;
uint m_handlers; // No. of handlers in this context
@ -290,8 +346,19 @@ private:
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
/*
Boundary for finding variables in this context. This is the number
of variables currently "invisible" to default clauses.
@ -300,7 +367,10 @@ private:
*/
uint m_pboundary;
int m_num_case_exprs;
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_cursor; // Cursors
DYNAMIC_ARRAY m_handler; // Handlers, for checking of duplicates

View file

@ -29,41 +29,137 @@
#include "sp_rcontext.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),
m_ihsp(0), m_hfound(-1), m_ccount(0), m_prev_ctx(prev)
sp_rcontext::sp_rcontext(sp_pcontext *root_parsing_ctx,
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::set_item_eval(THD *thd, uint idx, Item **item_addr,
enum_field_types type)
sp_rcontext::~sp_rcontext()
{
Item *it;
Item *reuse_it;
/* sp_eval_func_item will use callers_arena */
int res;
if (m_var_table)
free_blobs(m_var_table);
}
reuse_it= get_item(idx);
it= sp_eval_func_item(thd, item_addr, type, reuse_it, TRUE);
if (! it)
res= -1;
else
/*
Initialize sp_rcontext instance.
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;
set_item(idx, it);
if (!(m_var_items[idx]= new Item_field(m_var_table->field[idx])))
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
sp_rcontext::find_handler(uint sql_errno,
MYSQL_ERROR::enum_warning_level level)
@ -117,32 +213,14 @@ sp_rcontext::find_handler(uint sql_errno,
}
if (found < 0)
{
if (m_prev_ctx)
return m_prev_ctx->find_handler(sql_errno, level);
if (m_prev_runtime_ctx)
return m_prev_runtime_ctx->find_handler(sql_errno, level);
return FALSE;
}
m_hfound= found;
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
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);
}
void
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
@ -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, &current_arena);
holder= Item_cache::get_cache(result_type);
thd->restore_active_arena(thd->spcont->callers_arena, &current_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
****************************************************************************/
@ -294,11 +503,8 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items)
*/
for (; pv= pv_iter++, item= item_iter++; )
{
Item *reuse= thd->spcont->get_item(pv->offset);
/* Evaluate a new item on the arena of the calling instruction */
Item *it= sp_eval_func_item(thd, &item, pv->type, reuse, TRUE);
thd->spcont->set_item(pv->offset, it);
if (thd->spcont->set_variable(thd, pv->offset, item))
return TRUE;
}
return FALSE;
}

View file

@ -43,12 +43,22 @@ typedef struct
/*
This is a run context? of one SP ?
THis is
- a stack of cursors?
- a stack of handlers?
- a stack of Items ?
- a stack of instruction locations in SP?
This class is a runtime context of a Stored Routine. It is used in an
execution and is intended to contain all dynamic objects (i.e. objects, which
can be changed during execution), such as:
- stored routine variables;
- cursors;
- 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
@ -68,62 +78,34 @@ class sp_rcontext : public Sql_alloc
#ifndef DBUG_OFF
/*
Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling.
The routine for which this runtime context is created. Used for checking
if correct runtime context is used for variable handling.
*/
sp_head *owner;
sp_head *sp;
#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()
{
// Not needed?
//sql_element_free(m_frame);
//m_saved.empty();
}
~sp_rcontext();
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
set_item_eval(THD *thd, uint idx, Item **i, enum_field_types type);
set_variable(THD *thd, uint var_idx, Item *value);
inline Item *
get_item(uint idx)
Item *
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];
}
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;
return m_return_value_set;
}
inline void
@ -195,14 +177,6 @@ class sp_rcontext : public Sql_alloc
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
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];
}
/*
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:
sp_pcontext *m_root_parsing_ctx;
uint m_count;
uint m_fsize;
Item **m_frame;
/* Virtual table for storing variables. */
TABLE *m_var_table;
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
uint m_hcount; // Stack pointer for m_handler
@ -236,13 +239,22 @@ private:
uint *m_in_handler; // Active handler, for recursion check
uint m_ihsp; // Stack pointer for m_in_handler
int m_hfound; // Set by find_handler; -1 if not found
List<Item> m_saved; // Saved variables during handler exec.
sp_cursor **m_cstack;
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

View file

@ -2760,8 +2760,9 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
uint unused_field_idx= NO_CACHED_FIELD_INDEX;
TABLE_LIST *dummy;
Field *f=find_field_in_table_ref(thd, table_list, column->column.ptr(),
column->column.length(),
column->column.ptr(), NULL, NULL,
column->column.length(), 0, 1, 1, 0,
NULL, TRUE, FALSE,
&unused_field_idx, FALSE, &dummy);
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,
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_COLUMN *grant_column;
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);
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:
rw_unlock(&LOCK_grant);
if (!show_tables)
{
char command[128];
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
command,
sctx->priv_user,
sctx->host_or_ip,
name,
table_name);
}
char command[128];
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
command,
sctx->priv_user,
sctx->host_or_ip,
name,
table_name);
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,
const char* db_name, const char *table_name,
Field_iterator *fields)

View file

@ -205,7 +205,9 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint show_command, uint number, bool dont_print_error);
bool check_grant_column (THD *thd, GRANT_INFO *grant,
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,
const char* db_name, const char *table_name,
Field_iterator *fields);

View file

@ -2616,15 +2616,25 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
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;
DBUG_ASSERT(thd->lex->query_tables == *start);
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
if ((sp_cache_routines_and_add_tables(thd, thd->lex,
first_no_prelocking) ||
*start) && need_prelocking)
if (sp_cache_routines_and_add_tables(thd, thd->lex,
first_no_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;
*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)
{
if (!query_tables_last_own)
query_tables_last_own= thd->lex->query_tables_last;
sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
tables->table->triggers);
query_tables_last_own= thd->lex->query_tables_last;
if (sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
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));
}
@ -2771,9 +2790,21 @@ process_view_routines:
/* We have at least one table in TL here. */
if (!query_tables_last_own)
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;
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.
@ -3386,11 +3376,10 @@ static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
thd thread handler
table_list view to search for 'name'
name name of field
item_name name of item if it will be created (VIEW)
length length of name
item_name name of item if it will be created (VIEW)
ref expression substituted in VIEW should be passed
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
need register changes in item tree
@ -3402,8 +3391,8 @@ static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
static Field *
find_field_in_view(THD *thd, TABLE_LIST *table_list,
const char *name, const char *item_name,
uint length, Item **ref, bool check_grants,
const char *name, uint length,
const char *item_name, Item **ref,
bool register_tree_change)
{
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 (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
if (register_tree_change)
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);
if (register_tree_change && arena)
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
ref [in/out] if 'name' is resolved to a view field, ref is
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
need register changes in item tree
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 *
find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
uint length, Item **ref, bool check_grants,
bool register_tree_change,
uint length, Item **ref, bool register_tree_change,
TABLE_LIST **actual_table)
{
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;
}
#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)
{
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)
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);
if (register_tree_change && arena)
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
name name of field
length length of name
check_grants do check columns grants?
allow_rowid do allow finding of "_rowid" field?
cached_field_index_ptr cached position in field list (used to speedup
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 *
find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
bool check_grants, bool allow_rowid,
uint *cached_field_index_ptr,
Security_context *sctx)
bool allow_rowid, uint *cached_field_index_ptr)
{
Field **field_ptr, *field;
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);
#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);
}
@ -3671,14 +3630,13 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
thd [in] thread handler
table_list [in] table reference to search
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
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
is set to point to the found view field
check_grants_table [in] do check columns grants for table?
check_grants_view [in] do check columns grants for view?
check_privileges [in] check privileges
allow_rowid [in] do allow finding of "_rowid" field?
cached_field_index_ptr [in] cached position in field list (used to
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 *
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
const char *name, const char *item_name,
const char *table_name, const char *db_name,
uint length, Item **ref,
bool check_grants_table, bool check_grants_view,
bool allow_rowid, uint *cached_field_index_ptr,
const char *name, uint length,
const char *item_name, const char *db_name,
const char *table_name, Item **ref,
bool check_privileges, bool allow_rowid,
uint *cached_field_index_ptr,
bool register_tree_change, TABLE_LIST **actual_table)
{
Field *fld;
@ -3757,8 +3715,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
if (table_list->field_translation)
{
/* 'table_list' is a view or an information schema table. */
if ((fld= find_field_in_view(thd, table_list, name, item_name, length,
ref, check_grants_view,
if ((fld= find_field_in_view(thd, table_list, name, length, item_name, ref,
register_tree_change)))
*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. */
DBUG_ASSERT(table_list->table);
if ((fld= find_field_in_table(thd, table_list->table, name, length,
check_grants_table, allow_rowid,
cached_field_index_ptr,
table_list->security_ctx)))
allow_rowid,
cached_field_index_ptr)))
*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
{
@ -3797,11 +3743,10 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
TABLE_LIST *table;
while ((table= it++))
{
if ((fld= find_field_in_table_ref(thd, table, name, item_name,
table_name, db_name, length, ref,
check_grants_table,
check_grants_view,
allow_rowid, cached_field_index_ptr,
if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
db_name, table_name, ref,
check_privileges, allow_rowid,
cached_field_index_ptr,
register_tree_change, actual_table)))
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.
*/
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);
}
#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);
}
@ -3936,21 +3886,11 @@ find_field_in_tables(THD *thd, Item_ident *item,
*/
if (table_ref->table && !table_ref->view)
found= find_field_in_table(thd, table_ref->table, name, length,
test(table_ref->table->
grant.want_privilege) &&
check_privileges,
1, &(item->cached_field_index),
table_ref->security_ctx);
TRUE, &(item->cached_field_index));
else
found= find_field_in_table_ref(thd, table_ref, name, item->name,
NULL, NULL, length, ref,
(table_ref->table &&
test(table_ref->table->grant.
want_privilege) &&
check_privileges),
(test(table_ref->grant.want_privilege) &&
check_privileges),
1, &(item->cached_field_index),
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
NULL, NULL, ref, check_privileges,
TRUE, &(item->cached_field_index),
register_tree_change,
&actual_table);
if (found)
@ -3990,17 +3930,9 @@ find_field_in_tables(THD *thd, Item_ident *item,
for (; cur_table != last_table ;
cur_table= cur_table->next_name_resolution_table)
{
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, item->name,
table_name, db,
length, ref,
(cur_table->table &&
test(cur_table->table->grant.
want_privilege) &&
check_privileges),
(test(cur_table->grant.
want_privilege)
&& check_privileges),
allow_rowid,
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
item->name, db, table_name, ref,
check_privileges, allow_rowid,
&(item->cached_field_index),
register_tree_change,
&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 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;
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;
Natural_join_column *cur_nj_col_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;
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. */
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)))
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);
nj_col_1= it_1.get_natural_column_ref();
if (nj_col_1->is_common)
{
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. */
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)))
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);
nj_col_2= it_2.get_natural_column_ref();
if (!nj_col_2->is_common)
non_join_columns->push_back(nj_col_2);
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.
*/
Natural_join_column *nj_col;
if (!(nj_col= field_iterator.get_or_create_column_ref(thd,
&is_created)))
if (!(nj_col= field_iterator.get_or_create_column_ref(&is_created)))
DBUG_RETURN(TRUE);
DBUG_ASSERT(nj_col->table_field && !is_created);
field_table= nj_col->table_ref->table;

View file

@ -1505,10 +1505,10 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
my_var *mv= gl++;
if (mv->local)
{
Item_splocal *var;
(void)local_vars.push_back(var= new Item_splocal(mv->s, mv->offset));
Item_splocal *var= new Item_splocal(mv->s, mv->offset, mv->type);
(void)local_vars.push_back(var);
#ifndef DBUG_OFF
var->owner= mv->owner;
var->m_sp= mv->sp;
#endif
}
else
@ -1781,8 +1781,8 @@ bool select_dumpvar::send_data(List<Item> &items)
{
if ((yy=var_li++))
{
if (thd->spcont->set_item_eval(current_thd,
yy->get_offset(), it.ref(), zz->type))
if (thd->spcont->set_variable(current_thd, yy->get_var_idx(),
*it.ref()))
DBUG_RETURN(1);
}
}

View file

@ -2111,7 +2111,7 @@ public:
Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling.
*/
sp_head *owner;
sp_head *sp;
#endif
bool local;
uint offset;

View file

@ -113,11 +113,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
{ // Part field list
SELECT_LEX *select_lex= &thd->lex->select_lex;
Name_resolution_context *context= &select_lex->context;
TABLE_LIST *save_next_local;
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;
Name_resolution_context_state ctx_state;
int res;
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;
/* Save the state of the current name resolution context. */
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;
ctx_state.save_state(context, 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);
/* Restore the current context. */
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;
ctx_state.restore_state(context, table_list);
thd->lex->select_lex.no_wrap_view_item= FALSE;
if (res)
@ -293,13 +276,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
ulonglong id;
COPY_INFO info;
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_item *values;
Name_resolution_context *context;
Name_resolution_context_state ctx_state;
#ifndef EMBEDDED_LIBRARY
char *query= thd->query;
#endif
@ -380,13 +360,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
context= &thd->lex->select_lex.context;
/* Save the state of the current name resolution context. */
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;
ctx_state.save_state(context, 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 ();
/* Restore the current context. */
table_list->next_local= save_next_local;
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;
ctx_state.restore_state(context, table_list);
/*
Fill in the given fields and dump it to the table file
*/
info.records= info.deleted= info.copied= info.updated= 0;
info.ignore= ignore;
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;
Name_resolution_context *context= &select_lex->context;
TABLE_LIST *save_table_list;
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;
Name_resolution_context_state ctx_state;
bool insert_into_view= (table_list->view != 0);
bool res= 0;
DBUG_ENTER("mysql_prepare_insert");
@ -871,15 +836,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE);
/* Save the state of the current name resolution context. */
save_table_list= 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;
ctx_state.save_state(context, 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)
{
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() */
context->first_name_resolution_table->
next_name_resolution_table= save_next_local;
next_name_resolution_table= ctx_state.save_next_local;
}
if (!res)
res= setup_fields(thd, 0, update_values, 1, 0, 0);
}
/* Restore the current context. */
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;
ctx_state.restore_state(context, table_list);
if (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. */
Name_resolution_context *context= &lex->select_lex.context;
TABLE_LIST *save_table_list;
TABLE_LIST *save_next_local;
TABLE_LIST *save_first_name_resolution_table;
TABLE_LIST *save_next_name_resolution_table;
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;
Name_resolution_context_state ctx_state;
/* Save the state of the current name resolution context. */
ctx_state.save_state(context, table_list);
/* Perform name resolution only in the first table - 'table_list'. */
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)
{
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() */
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);
/* Restore the current context. */
table_list->next_local= save_next_local;
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;
ctx_state.restore_state(context, table_list);
}
lex->current_select= lex_current_select_save;

View file

@ -1130,6 +1130,11 @@ void st_select_lex::init_query()
/*
Add the name resolution context of the current (sub)query to the
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);
cond_count= with_wild= 0;

View file

@ -1024,9 +1024,9 @@ typedef struct st_lex
}
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()

View file

@ -266,10 +266,21 @@ protected:
ls.elements= elm;
}
public:
base_list_iterator(base_list &list_par)
:list(&list_par), el(&list_par.first), prev(0), current(0)
base_list_iterator()
: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)
{
prev=el;
@ -364,6 +375,8 @@ template <class T> class List_iterator :public base_list_iterator
{
public:
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 *replace(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:
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 void rewind(void) { base_list_iterator::rewind(); }
void sublist(List<T> &list_arg, uint el_arg)

View file

@ -2614,7 +2614,8 @@ mysql_execute_command(THD *thd)
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_backup_table(thd, first_table);
select_lex->table_list.first= (byte*) first_table;
lex->query_tables=all_tables;
break;
}
case SQLCOM_RESTORE_TABLE:
@ -2626,6 +2627,8 @@ mysql_execute_command(THD *thd)
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_restore_table(thd, first_table);
select_lex->table_list.first= (byte*) first_table;
lex->query_tables=all_tables;
break;
}
case SQLCOM_ASSIGN_TO_KEYCACHE:
@ -3119,6 +3122,8 @@ end_with_restore_list:
mysql_bin_log.write(&qinfo);
}
}
select_lex->table_list.first= (byte*) first_table;
lex->query_tables=all_tables;
break;
}
case SQLCOM_CHECK:
@ -3129,6 +3134,8 @@ end_with_restore_list:
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_check_table(thd, first_table, &lex->check_opt);
select_lex->table_list.first= (byte*) first_table;
lex->query_tables=all_tables;
break;
}
case SQLCOM_ANALYZE:
@ -3149,6 +3156,8 @@ end_with_restore_list:
mysql_bin_log.write(&qinfo);
}
}
select_lex->table_list.first= (byte*) first_table;
lex->query_tables=all_tables;
break;
}
@ -3172,6 +3181,8 @@ end_with_restore_list:
mysql_bin_log.write(&qinfo);
}
}
select_lex->table_list.first= (byte*) first_table;
lex->query_tables=all_tables;
break;
}
case SQLCOM_UPDATE:
@ -4122,14 +4133,6 @@ end_with_restore_list:
}
}
#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
@ -5765,9 +5768,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
buf, "TIMESTAMP");
}
if (!(new_field= new_create_field(thd, field_name, type, length, decimals,
type_modifier, default_value, on_update_value,
comment, change, interval_list, cs, uint_geom_type)))
if (!(new_field= new create_field()) ||
new_field->init(thd, field_name, type, length, decimals, type_modifier,
default_value, on_update_value, comment, change,
interval_list, cs, uint_geom_type))
DBUG_RETURN(1);
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);
}
/*****************************************************************************
** 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 */
@ -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
make_join_on_context()
push_new_name_resolution_context()
thd pointer to current thread
left_op left operand of the JOIN
right_op rigth operand of the JOIN
DESCRIPTION
Create a new name resolution context for a JOIN ... ON clause,
and set the first and last leaves of the list of table references
to be used for name resolution.
set the first and last leaves of the list of table references
to be used for name resolution, and push the newly created
context to the stack of contexts of the query.
RETURN
A new context if all is OK
NULL - if a memory allocation error occured
FALSE if all is OK
TRUE if a memory allocation error occured
*/
Name_resolution_context *
make_join_on_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op)
bool
push_new_name_resolution_context(THD *thd,
TABLE_LIST *left_op, TABLE_LIST *right_op)
{
Name_resolution_context *on_context;
if (!(on_context= new (thd->mem_root) Name_resolution_context))
return NULL;
return TRUE;
on_context->init();
on_context->first_name_resolution_table=
left_op->first_leaf_for_name_resolution();
on_context->last_name_resolution_table=
right_op->last_leaf_for_name_resolution();
return on_context;
return thd->lex->push_context(on_context);
}

View file

@ -8951,6 +8951,7 @@ err:
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
{
uint field_count= field_list.elements;
uint blob_count= 0;
Field **field;
create_field *cdef; /* column definition */
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);
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 */
List_iterator_fast<create_field> it(field_list);
while ((cdef= it++))
@ -8983,9 +8990,15 @@ TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
record_length+= (*field)->pack_length();
if (! ((*field)->flags & NOT_NULL_FLAG))
null_count++;
if ((*field)->flags & BLOB_FLAG)
share->blob_field[blob_count++]= (uint) (field - table->field);
field++;
}
*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;
share->reclength= record_length + null_pack_length;

View file

@ -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,
ulonglong select_options, ha_rows rows_limit,
char* alias);
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list);
void free_tmp_table(THD *thd, TABLE *entry);
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool reset_with_sum_func);

View file

@ -2412,18 +2412,14 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
*/
lex->query_tables= table;
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;
if (view_operator_func == NULL)
table->required_type=FRMTYPE_TABLE;
open_and_lock_tables(thd, table);
thd->no_warnings_for_error= 0;
table->next_global= save_next_global;
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;
if (prepare_func)

View file

@ -1123,7 +1123,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
trg_action_time_type time_type,
bool old_row_is_record1)
{
int res= 0;
bool err_status= FALSE;
sp_head *sp_trigger= bodies[event][time_type];
if (sp_trigger)
@ -1183,7 +1183,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
#endif // NO_EMBEDDED_ACCESS_CHECKS
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);
#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
}
return res;
return err_status;
}

View file

@ -117,7 +117,7 @@ public:
void set_table(TABLE *new_table);
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);
private:

View file

@ -1377,41 +1377,11 @@ create_function_tail:
{
LEX *lex= Lex;
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*) "",
(enum enum_field_types)$8,
lex->length, lex->dec, lex->type,
(Item *)0, (Item *) 0, &cmt, 0,
&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;
if (sp->fill_field_definition(YYTHD, lex,
(enum enum_field_types) $8,
&sp->m_return_field_def))
YYABORT;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
@ -1434,6 +1404,11 @@ create_function_tail:
YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
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 */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
@ -1528,8 +1503,28 @@ sp_fdparams:
| 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:
ident type
ident sp_init_param type
{
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@ -1539,7 +1534,17 @@ sp_fdparam:
my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
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_opt_inout ident type
sp_opt_inout sp_init_param ident type
{
LEX *lex= Lex;
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;
}
spc->push_pvar(&$2, (enum enum_field_types)$3,
(sp_param_mode_t)$1);
sp_pvar_t *pvar= spc->push_pvar(&$3, (enum enum_field_types)$4,
(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:
DECLARE_SYM sp_decl_idents type
DECLARE_SYM sp_decl_idents
{
LEX *lex= Lex;
lex->sphead->reset_lex(YYTHD);
lex->spcont->declare_var_boundary($2);
}
type
sp_opt_default
{
LEX *lex= Lex;
sp_pcontext *ctx= lex->spcont;
uint max= ctx->context_pvars();
enum enum_field_types type= (enum enum_field_types)$3;
Item *it= $5;
bool has_default= (it != NULL);
for (uint i = max-$2 ; i < max ; i++)
sp_pcontext *pctx= lex->spcont;
uint num_vars= pctx->context_pvars();
enum enum_field_types var_type= (enum enum_field_types) $4;
Item *dflt_value_item= $5;
create_field *create_field_op;
if (!dflt_value_item)
{
sp_instr_set *in;
uint off= ctx->pvar_context2index(i);
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);
dflt_value_item= new Item_null();
/* QQ Set to the var_type with null_value? */
}
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);
$$.vars= $2;
$$.conds= $$.hndlrs= $$.curs= 0;
}
@ -1879,6 +1908,8 @@ sp_hcond:
sp_decl_idents:
ident
{
/* NOTE: field definition is filled in sp_decl section. */
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@ -1892,6 +1923,8 @@ sp_decl_idents:
}
| sp_decl_idents ',' ident
{
/* NOTE: field definition is filled in sp_decl section. */
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@ -1969,8 +2002,8 @@ sp_proc_stmt:
{
sp_instr_freturn *i;
i= new sp_instr_freturn(sp->instructions(), lex->spcont,
$3, sp->m_returns, lex);
i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3,
sp->m_return_field_def.sql_type, lex);
sp->add_instr(i);
sp->m_flags|= sp_head::HAS_RETURN;
}
@ -1986,25 +2019,27 @@ sp_proc_stmt:
{ Lex->sphead->reset_lex(YYTHD); }
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;
uint offset= lex->spcont->current_pvars();
sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(),
lex->spcont, offset, $3,
MYSQL_TYPE_STRING, lex, TRUE);
LEX_STRING dummy={(char*)"", 0};
lex->spcont->push_pvar(&dummy, MYSQL_TYPE_STRING, sp_param_in);
lex->sphead->add_instr(i);
lex->sphead->m_flags|= sp_head::IN_SIMPLE_CASE;
lex->sphead->restore_lex(YYTHD);
sp_head *sp= lex->sphead;
sp_pcontext *parsing_ctx= lex->spcont;
int case_expr_id= parsing_ctx->register_case_expr();
if (parsing_ctx->push_case_expr_id(case_expr_id))
YYABORT;
sp->add_instr(
new sp_instr_set_case_expr(sp->instructions(),
parsing_ctx,
case_expr_id,
$3,
lex));
sp->m_flags|= sp_head::IN_SIMPLE_CASE;
sp->restore_lex(YYTHD);
}
sp_case END CASE_SYM
{
Lex->spcont->pop_pvar();
Lex->spcont->pop_case_expr_id();
}
| sp_labeled_control
{}
@ -2315,20 +2350,20 @@ sp_case:
i= new sp_instr_jump_if_not(ip, ctx, $2, lex);
else
{ /* Simple case: <caseval> = <whenval> */
LEX_STRING ivar;
ivar.str= (char *)"_tmp_";
ivar.length= 5;
Item_splocal *var= new Item_splocal(ivar,
ctx->current_pvars()-1);
Item_case_expr *var;
Item *expr;
var= new Item_case_expr(ctx->get_current_case_expr_id());
#ifndef DBUG_OFF
if (var)
var->owner= sp;
var->m_sp= sp;
#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);
lex->variables_used= 1;
}
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
sp->add_instr(i);
@ -4401,11 +4436,6 @@ optimize:
OPTIMIZE opt_no_write_to_binlog table_or_tables
{
LEX *lex=Lex;
if (lex->sphead)
{
my_error(ER_SP_BADSTATEMENT, MYF(0), "OPTIMIZE TABLE");
YYABORT;
}
lex->sql_command = SQLCOM_OPTIMIZE;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
@ -5024,11 +5054,9 @@ simple_expr:
{
if ($3->is_splocal())
{
LEX_STRING *name;
Item_splocal *il= static_cast<Item_splocal *>($3);
name= il->my_name(NULL);
my_error(ER_WRONG_COLUMN_NAME, MYF(0), name->str);
my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
YYABORT;
}
$$= new Item_default_value(Lex->current_context(), $3);
@ -5803,10 +5831,8 @@ join_table:
{
YYERROR_UNLESS($1 && ($$=$3));
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
Lex->push_context(on_context);
}
expr
{
@ -5818,10 +5844,8 @@ join_table:
{
YYERROR_UNLESS($1 && ($$=$3));
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
Lex->push_context(on_context);
}
expr
{
@ -5848,10 +5872,8 @@ join_table:
ON
{
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
Lex->push_context(on_context);
}
expr
{
@ -5881,10 +5903,8 @@ join_table:
ON
{
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
Lex->push_context(on_context);
}
expr
{
@ -5945,10 +5965,9 @@ table_factor:
ON
{
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$3,$7)))
if (push_new_name_resolution_context(YYTHD, $3, $7))
YYABORT;
Lex->push_context(on_context);
}
expr '}'
{
@ -6505,7 +6524,7 @@ select_var_ident:
var_list.push_back(var= new my_var($1,1,t->offset,t->type));
#ifndef DBUG_OFF
if (var)
var->owner= lex->sphead;
var->sp= lex->sphead;
#endif
}
}
@ -7816,11 +7835,12 @@ simple_ident:
{
/* We're compiling a stored procedure and found a variable */
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);
#ifndef DBUG_OFF
if (splocal)
splocal->owner= lex->sphead;
splocal->m_sp= lex->sphead;
#endif
$$ = (Item*) splocal;
lex->variables_used= 1;

View file

@ -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)
{
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)
{
/*
In case of SHOW command (schema_table_reformed set) all items are
fixed
Translation table items are always Item_fields and already 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_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)
{
DBUG_ASSERT(table_ref->join_columns);
delete 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)++;
column_ref_it.init(*(table_ref->join_columns));
cur_column_ref= column_ref_it++;
}
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 ||
cur_column_ref->table_ref->table ==
cur_column_ref->table_field->table);
@ -3350,7 +3290,6 @@ GRANT_INFO *Field_iterator_table_ref::grant()
SYNOPSIS
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,
FALSE if we return an already created colum
@ -3363,7 +3302,7 @@ GRANT_INFO *Field_iterator_table_ref::grant()
*/
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;
@ -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
*****************************************************************************/

View file

@ -432,9 +432,6 @@ public:
const char *table_name();
const char *db_name();
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
{
List_iterator_fast<Natural_join_column> *column_ref_it;
List_iterator_fast<Natural_join_column> column_ref_it;
Natural_join_column *cur_column_ref;
public:
Field_iterator_natural_join() :column_ref_it(NULL), cur_column_ref(NULL) {}
~Field_iterator_natural_join() { delete column_ref_it; }
Field_iterator_natural_join() :cur_column_ref(NULL) {}
~Field_iterator_natural_join() {}
void set(TABLE_LIST *table);
void next();
bool end_of_fields() { return !cur_column_ref; }
@ -811,7 +808,8 @@ public:
GRANT_INFO *grant();
Item *create_item(THD *thd) { return field_it->create_item(thd); }
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();
};

View file

@ -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
@ -10,7 +10,7 @@ the Web at http://www.sleepycat.com.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/*
* Copyright (c) 1990-2004
* Copyright (c) 1990-2005
* Sleepycat Software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -24,13 +24,12 @@ top_srcdir = @top_srcdir@
bdb_build = build_unix
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 \
db_dump185 db_load db_printlog db_recover db_stat db_upgrade \
db_verify dbm dbreg dist env examples_c examples_cxx fileops hash \
hsearch hmac include java libdb_java lock log mp mutex os os_vxworks \
os_win32 perl.BerkeleyDB perl.DB_File qam rep rpc_client rpc_server tcl \
test txn xa sequence
db_dump185 db_hotbackup db_load db_printlog db_recover db_stat db_upgrade \
db_verify dbm dbreg dist env fileops hash \
hsearch hmac include lock log mp mutex os \
os_win32 qam rep txn xa sequence
@SET_MAKE@

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* Sleepycat Software. All rights reserved.
*/
/*
@ -39,7 +39,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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"

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* 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"
@ -88,7 +88,7 @@ __bam_mswap(pg)
p = (u_int8_t *)pg + sizeof(DBMETA);
SWAP32(p); /* maxkey */
p += sizeof(u_int32_t); /* unused */
SWAP32(p); /* minkey */
SWAP32(p); /* re_len */
SWAP32(p); /* re_pad */

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* 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"
@ -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
* 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
__bam_ca_delete(dbp, pgno, indx, delete)
__bam_ca_delete(dbp, pgno, indx, delete, countp)
DB *dbp;
db_pgno_t pgno;
u_int32_t indx;
int delete;
int delete, *countp;
{
BTREE_CURSOR *cp;
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
* 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);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
MUTEX_LOCK(dbenv, dbp->mutex);
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
cp = (BTREE_CURSOR *)dbc->internal;
@ -92,23 +92,26 @@ __bam_ca_delete(dbp, pgno, indx, delete)
++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 --
* 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
__ram_ca_delete(dbp, root_pgno)
__ram_ca_delete(dbp, root_pgno, foundp)
DB *dbp;
db_pgno_t root_pgno;
int *foundp;
{
DB *ldbp;
DBC *dbc;
@ -121,19 +124,21 @@ __ram_ca_delete(dbp, root_pgno)
/*
* 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);
found == 0 && ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
MUTEX_LOCK(dbenv, dbp->mutex);
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
found == 0 && dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
if (dbc->internal->root == root_pgno)
found = 1;
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
MUTEX_UNLOCK(dbenv, dbp->mutex);
}
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
return (found);
MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
*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().
*/
found = 0;
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
MUTEX_LOCK(dbenv, dbp->mutex);
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
if (dbc->dbtype == DB_RECNO)
@ -188,9 +193,9 @@ __bam_ca_di(my_dbc, pgno, indx, adjust)
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 ((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().
*/
found = 0;
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
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);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
/* Find cursors pointing to this record. */
@ -308,7 +313,7 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
if (orig_cp->opd != NULL)
continue;
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
MUTEX_UNLOCK(dbenv, dbp->mutex);
/* [#8032]
DB_ASSERT(!STD_LOCKING(dbc) ||
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. */
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 ((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().
*/
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
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);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
orig_cp = (BTREE_CURSOR *)dbc->internal;
@ -377,11 +382,10 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
*/
if (orig_cp->pgno != fpgno ||
orig_cp->indx != first ||
orig_cp->opd == NULL ||
((BTREE_CURSOR *)orig_cp->opd->internal)->indx
!= ti)
orig_cp->opd == NULL || ((BTREE_CURSOR *)
orig_cp->opd->internal)->indx != ti)
continue;
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
MUTEX_UNLOCK(dbenv, dbp->mutex);
if ((ret = __db_c_close(orig_cp->opd)) != 0)
return (ret);
orig_cp->opd = NULL;
@ -392,9 +396,9 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
*/
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);
}
@ -425,11 +429,11 @@ __bam_ca_rsplit(my_dbc, fpgno, tpgno)
* Adjust the cursors. See the comment in __bam_ca_delete().
*/
found = 0;
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
MUTEX_LOCK(dbenv, dbp->mutex);
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
if (dbc->dbtype == DB_RECNO)
@ -444,9 +448,9 @@ __bam_ca_rsplit(my_dbc, fpgno, tpgno)
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 ((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.
*/
found = 0;
MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);
MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
MUTEX_LOCK(dbenv, dbp->mutex);
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
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 ((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.
* 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));
*/
void
int
__bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx)
DB *dbp;
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
* 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);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
MUTEX_LOCK(dbenv, dbp->mutex);
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
if (dbc->dbtype == DB_RECNO)
@ -578,7 +582,9 @@ __bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx)
} else if (cp->pgno == lpgno)
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);
}

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* 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"
@ -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_del __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_getstack __P((DBC *));
static int __bam_c_last __P((DBC *));
static int __bam_c_next __P((DBC *, int, int));
static int __bam_c_physdel __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)); \
} 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. */
#undef ACQUIRE_CUR
#define ACQUIRE_CUR(dbc, mode, p, ret) do { \
@ -96,23 +79,6 @@ static int __bam_isopd __P((DBC *, db_pgno_t *));
} \
} 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.
*
@ -196,11 +162,11 @@ __bam_c_init(dbc, dbtype)
/* Allocate/initialize the internal structure. */
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);
/* Initialize methods. */
dbc->c_close = __db_c_close;
dbc->c_close = __db_c_close_pp;
dbc->c_count = __db_c_count_pp;
dbc->c_del = __db_c_del_pp;
dbc->c_dup = __db_c_dup_pp;
@ -257,8 +223,11 @@ __bam_c_refresh(dbc)
LOCK_INIT(cp->lock);
cp->lock_mode = DB_LOCK_NG;
cp->sp = cp->csp = cp->stack;
cp->esp = cp->stack + sizeof(cp->stack) / sizeof(cp->stack[0]);
if (cp->sp == NULL) {
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
@ -308,7 +277,7 @@ __bam_c_close(dbc, root_pgno, rmroot)
DBC *dbc_opd, *dbc_c;
DB_MPOOLFILE *mpf;
PAGE *h;
int cdb_lock, ret;
int cdb_lock, count, ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
@ -378,22 +347,28 @@ __bam_c_close(dbc, root_pgno, rmroot)
dbc_c = dbc;
switch (dbc->dbtype) {
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 done;
case DB_RECNO:
if (!F_ISSET(dbc, DBC_OPD)) /* Case #1. */
goto done;
/* 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 done;
case DB_HASH:
case DB_QUEUE:
case DB_UNKNOWN:
default:
return (__db_unknown_type(dbp->dbenv,
"__bam_c_close", dbc->dbtype));
ret = __db_unknown_type(dbp->dbenv,
"__bam_c_close", dbc->dbtype);
goto err;
}
}
@ -414,20 +389,26 @@ __bam_c_close(dbc, root_pgno, rmroot)
dbc_c = dbc_opd;
switch (dbc_opd->dbtype) {
case DB_BTREE:
if (__bam_ca_delete(
dbp, cp_opd->pgno, cp_opd->indx, 1) == 0)
if ((ret = __bam_ca_delete(
dbp, cp_opd->pgno, cp_opd->indx, 1, &count)) != 0)
goto err;
if (count == 0)
goto lock;
goto done;
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 done;
case DB_HASH:
case DB_QUEUE:
case DB_UNKNOWN:
default:
return (__db_unknown_type(
dbp->dbenv, "__bam_c_close", dbc->dbtype));
ret = __db_unknown_type(
dbp->dbenv, "__bam_c_close", dbc->dbtype);
goto err;
}
}
goto done;
@ -588,8 +569,14 @@ static int
__bam_c_destroy(dbc)
DBC *dbc;
{
BTREE_CURSOR *cp;
cp = (BTREE_CURSOR *)dbc->internal;
/* 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);
}
@ -693,7 +680,7 @@ __bam_c_del(dbc)
BTREE_CURSOR *cp;
DB *dbp;
DB_MPOOLFILE *mpf;
int ret, t_ret;
int count, ret, t_ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
@ -760,9 +747,12 @@ err: /*
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)
(void)__bam_ca_delete(dbp, cp->pgno, cp->indx, 1);
ret = __bam_ca_delete(dbp, cp->pgno, cp->indx, 1, &count);
return (ret);
}
@ -846,7 +836,8 @@ __bam_c_get(dbc, key, data, flags, pgnop)
break;
case DB_FIRST:
newopd = 1;
if ((ret = __bam_c_first(dbc)) != 0)
if ((ret = __bam_c_search(dbc,
PGNO_INVALID, NULL, flags, &exact)) != 0)
goto err;
break;
case DB_GET_BOTH:
@ -910,13 +901,15 @@ __bam_c_get(dbc, key, data, flags, pgnop)
break;
case DB_LAST:
newopd = 1;
if ((ret = __bam_c_last(dbc)) != 0)
if ((ret = __bam_c_search(dbc,
PGNO_INVALID, NULL, flags, &exact)) != 0)
goto err;
break;
case DB_NEXT:
newopd = 1;
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;
} else
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:
newopd = 1;
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;
} else
do {
@ -944,7 +938,8 @@ __bam_c_get(dbc, key, data, flags, pgnop)
case DB_PREV:
newopd = 1;
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;
} else
if ((ret = __bam_c_prev(dbc)) != 0)
@ -953,7 +948,8 @@ __bam_c_get(dbc, key, data, flags, pgnop)
case DB_PREV_NODUP:
newopd = 1;
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;
} else
do {
@ -2136,99 +2132,6 @@ __bam_c_writelock(dbc)
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 --
* Move to the next record.
@ -2398,6 +2301,12 @@ __bam_c_search(dbc, root_pgno, key, flags, exactp)
return (ret);
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:
if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0)
return (ret);
@ -2575,7 +2484,6 @@ search: if ((ret = __bam_search(dbc, root_pgno,
default:
return (__db_unknown_flag(dbp->dbenv, "__bam_c_search", flags));
}
/* Initialize the cursor from the stack. */
cp->page = cp->csp->page;
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_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);
}
@ -2597,15 +2515,10 @@ __bam_c_physdel(dbc)
BTREE_CURSOR *cp;
DB *dbp;
DBT key;
DB_LOCK lock;
DB_MPOOLFILE *mpf;
PAGE *h;
db_pgno_t pgno;
int delete_page, empty_page, exact, level, ret;
int delete_page, empty_page, exact, ret;
dbp = dbc->dbp;
memset(&key, 0, sizeof(DBT));
mpf = dbp->mpf;
cp = (BTREE_CURSOR *)dbc->internal;
delete_page = empty_page = ret = 0;
@ -2683,91 +2596,7 @@ __bam_c_physdel(dbc)
if (!delete_page)
return (0);
/*
* 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);
ret = __bam_search(dbc, PGNO_INVALID, &key, S_DEL, 0, NULL, &exact);
/*
* If everything worked, delete the stack, otherwise, release the
@ -2776,7 +2605,7 @@ __bam_c_physdel(dbc)
if (ret == 0)
DISCARD_CUR(dbc, ret);
if (ret == 0)
ret = __bam_dpages(dbc, cp->sp);
ret = __bam_dpages(dbc, 1, 0);
else
(void)__bam_stkrel(dbc, 0);

View file

@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* Sleepycat Software. All rights reserved.
*/
/*
@ -39,7 +39,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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"
@ -220,12 +220,13 @@ __bam_adjindx(dbc, h, indx, indx_copy, is_insert)
* __bam_dpages --
* Delete a set of locked pages.
*
* PUBLIC: int __bam_dpages __P((DBC *, EPG *));
* PUBLIC: int __bam_dpages __P((DBC *, int, int));
*/
int
__bam_dpages(dbc, stack_epg)
__bam_dpages(dbc, use_top, update)
DBC *dbc;
EPG *stack_epg;
int use_top;
int update;
{
BTREE_CURSOR *cp;
BINTERNAL *bi;
@ -233,7 +234,7 @@ __bam_dpages(dbc, stack_epg)
DBT a, b;
DB_LOCK c_lock, p_lock;
DB_MPOOLFILE *mpf;
EPG *epg;
EPG *epg, *save_sp, *stack_epg;
PAGE *child, *parent;
db_indx_t nitems;
db_pgno_t pgno, root_pgno;
@ -243,30 +244,27 @@ __bam_dpages(dbc, stack_epg)
dbp = dbc->dbp;
mpf = dbp->mpf;
cp = (BTREE_CURSOR *)dbc->internal;
nitems = 0;
pgno = PGNO_INVALID;
/*
* We have the entire stack of deletable pages locked.
*
* Btree calls us with a pointer to the beginning of a stack, where
* the first page in the stack is to have a single item deleted, and
* the rest of the pages are to be removed.
* Btree calls us with the first page in the stack is to have a
* single item deleted, and the rest of the pages are to be removed.
*
* Recno calls us with a pointer into the middle of the stack, where
* the referenced page is to have a single item deleted, and pages
* after the stack reference are to be removed.
*
* First, discard any pages that we don't care about.
* Recno always has a stack to the root and __bam_merge operations
* may have unneeded items in the sack. We find the lowest page
* in the stack that has more than one record in it and start there.
*/
ret = 0;
for (epg = cp->sp; epg < stack_epg; ++epg) {
if ((t_ret = __memp_fput(mpf, epg->page, 0)) != 0 && ret == 0)
ret = t_ret;
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
ret = t_ret;
}
if (ret != 0)
goto err;
if (use_top)
stack_epg = cp->sp;
else
for (stack_epg = cp->csp; stack_epg > cp->sp; --stack_epg)
if (NUM_ENT(stack_epg->page) > 1)
break;
epg = stack_epg;
/*
* !!!
* 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
* leaf page chain.
*/
if ((ret = __bam_relink(dbc, cp->csp->page, NULL)) != 0)
goto err;
if (LEVEL(cp->csp->page) == 1 &&
(ret = __bam_relink(dbc, cp->csp->page, PGNO_INVALID)) != 0)
goto discard;
/*
* Delete the last item that references the underlying pages that are
@ -288,9 +287,18 @@ __bam_dpages(dbc, stack_epg)
* immediately.
*/
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)
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);
nitems = NUM_ENT(epg->page);
@ -301,6 +309,17 @@ __bam_dpages(dbc, stack_epg)
if (ret != 0)
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. */
while (++epg <= cp->csp) {
/*
@ -310,13 +329,24 @@ __bam_dpages(dbc, stack_epg)
* be referenced by a cursor.
*/
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)
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);
if (cp->page == epg->page)
cp->page = NULL;
epg->page = NULL;
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
ret = t_ret;
@ -468,12 +498,13 @@ stop: done = 1;
* __bam_relink --
* Relink around a deleted page.
*
* PUBLIC: int __bam_relink __P((DBC *, PAGE *, PAGE **));
* PUBLIC: int __bam_relink __P((DBC *, PAGE *, db_pgno_t));
*/
int
__bam_relink(dbc, pagep, new_next)
__bam_relink(dbc, pagep, new_pgno)
DBC *dbc;
PAGE *pagep, **new_next;
PAGE *pagep;
db_pgno_t new_pgno;
{
DB *dbp;
PAGE *np, *pp;
@ -519,7 +550,7 @@ __bam_relink(dbc, pagep, new_next)
/* Log the change. */
if (DBC_LOGGING(dbc)) {
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)
goto err;
} else
@ -528,33 +559,27 @@ __bam_relink(dbc, pagep, new_next)
np->lsn = ret_lsn;
if (pp != NULL)
pp->lsn = ret_lsn;
pagep->lsn = ret_lsn;
/*
* 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) {
np->prev_pgno = pagep->prev_pgno;
if (new_next == NULL)
ret = __memp_fput(mpf, np, DB_MPOOL_DIRTY);
else {
*new_next = np;
ret = __memp_fset(mpf, np, DB_MPOOL_DIRTY);
}
if (new_pgno == PGNO_INVALID)
np->prev_pgno = pagep->prev_pgno;
else
np->prev_pgno = new_pgno;
ret = __memp_fput(mpf, np, DB_MPOOL_DIRTY);
if ((t_ret = __TLPUT(dbc, npl)) != 0 && ret == 0)
ret = t_ret;
if (ret != 0)
goto err;
} else if (new_next != NULL)
*new_next = 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);
if ((t_ret = __TLPUT(dbc, ppl)) != 0 && ret == 0)
ret = t_ret;
@ -571,3 +596,48 @@ err: if (np != NULL)
(void)__TLPUT(dbc, ppl);
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);
}

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1999-2004
* Copyright (c) 1999-2005
* 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"
@ -18,7 +18,6 @@
#include "dbinc/btree.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_prefix
__P((DB *, size_t(*)(DB *, const DBT *, const DBT *)));
@ -52,7 +51,6 @@ __bam_db_create(dbp)
t->bt_prefix = __bam_defpfx;
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->set_bt_minkey = __bam_set_bt_minkey;
dbp->set_bt_prefix = __bam_set_bt_prefix;
@ -208,31 +206,6 @@ __bam_set_bt_compare(dbp, func)
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 --
* Get the minimum keys per page.

View file

@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* Sleepycat Software. All rights reserved.
*/
/*
@ -39,7 +39,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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"
@ -311,7 +311,6 @@ __bam_read_root(dbp, txn, base_pgno, flags)
* metadata page will be created/initialized elsewhere.
*/
if (meta->dbmeta.magic == DB_BTREEMAGIC) {
t->bt_maxkey = meta->maxkey;
t->bt_minkey = meta->minkey;
t->re_pad = (int)meta->re_pad;
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);
t = dbp->bt_internal;
meta->maxkey = t->bt_maxkey;
meta->minkey = t->bt_minkey;
meta->re_len = t->re_len;
meta->re_pad = (u_int32_t)t->re_pad;
@ -428,7 +426,7 @@ __bam_new_file(dbp, txn, fhp, name)
DBT pdbt;
PAGE *root;
db_pgno_t pgno;
int ret;
int ret, t_ret;
void *buf;
dbenv = dbp->dbenv;
@ -437,7 +435,7 @@ __bam_new_file(dbp, txn, fhp, name)
meta = NULL;
buf = NULL;
if (name == NULL) {
if (F_ISSET(dbp, DB_AM_INMEM)) {
/* Build the meta-data page. */
pgno = PGNO_BASE_MD;
if ((ret =
@ -447,6 +445,9 @@ __bam_new_file(dbp, txn, fhp, name)
__bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
meta->root = 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);
meta = NULL;
if (ret != 0)
@ -460,6 +461,9 @@ __bam_new_file(dbp, txn, fhp, name)
P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
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);
root = NULL;
if (ret != 0)
@ -509,10 +513,12 @@ __bam_new_file(dbp, txn, fhp, name)
err: if (buf != NULL)
__os_free(dbenv, buf);
else {
if (meta != NULL)
(void)__memp_fput(mpf, meta, 0);
if (root != NULL)
(void)__memp_fput(mpf, root, 0);
if (meta != NULL &&
(t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
ret = t_ret;
if (root != NULL &&
(t_ret = __memp_fput(mpf, root, 0)) != 0 && ret == 0)
ret = t_ret;
}
return (ret);
}

View file

@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* Sleepycat Software. All rights reserved.
*/
/*
@ -39,7 +39,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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"
@ -58,7 +58,9 @@
static int __bam_build
__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
__P((DBC *, u_int32_t, db_pgno_t, PAGE *, u_int32_t, DBT *));
static u_int32_t
@ -84,11 +86,12 @@ __bam_iitem(dbc, key, data, op, flags)
DBT bk_hdr, tdbt;
DB_MPOOLFILE *mpf;
PAGE *h;
db_indx_t indx;
u_int32_t data_size, have_bytes, need_bytes, needed;
db_indx_t cnt, indx;
u_int32_t data_size, have_bytes, need_bytes, needed, pages, pagespace;
int cmp, bigkey, bigdata, dupadjust, padrec, replace, ret, was_deleted;
COMPQUIET(bk, NULL);
COMPQUIET(cnt, 0);
dbp = dbc->dbp;
dbenv = dbp->dbenv;
@ -217,13 +220,39 @@ __bam_iitem(dbc, key, data, op, flags)
return (__db_unknown_flag(dbenv, "DB->put", op));
}
/*
* 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.
*/
/* Split the page if there's not enough room. */
if (P_FREESPACE(dbp, h) < needed)
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:
*
@ -259,7 +288,6 @@ __bam_iitem(dbc, key, data, op, flags)
return (ret);
indx += 3;
dupadjust = 1;
cp->indx += 2;
} else {
@ -276,7 +304,6 @@ __bam_iitem(dbc, key, data, op, flags)
return (ret);
++indx;
dupadjust = 1;
}
break;
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
* 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) {
++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
* its own page.
*/
if (dupadjust && P_FREESPACE(dbp, h) <= dbp->pgsize / 2) {
if ((ret = __bam_dup_convert(dbc, h, indx - O_INDX)) != 0)
return (ret);
}
if (dupadjust &&
(ret = __bam_dup_convert(dbc, h, indx - O_INDX, cnt)) != 0)
return (ret);
/* If we've modified a recno file, set the flag. */
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.
* If it should, create it.
*/
static int
__bam_dup_convert(dbc, h, indx)
__bam_dup_check(dbc, op, h, indx, sz, cntp)
DBC *dbc;
u_int32_t op;
PAGE *h;
u_int32_t indx;
u_int32_t indx, sz;
db_indx_t *cntp;
{
BKEYDATA *bk;
DB *dbp;
DBT hdr;
DB_MPOOLFILE *mpf;
PAGE *dp;
db_indx_t cnt, cpindx, dindx, first, *inp, sz;
int ret;
db_indx_t cnt, first, *inp;
dbp = dbc->dbp;
mpf = dbp->mpf;
inp = P_INP(dbp, h);
/*
@ -695,11 +717,21 @@ __bam_dup_convert(dbc, h, indx)
/* Count the key once. */
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;
/* 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];
++cnt, indx += P_INDX) {
bk = GET_BKEYDATA(dbp, h, indx + O_INDX);
@ -726,6 +758,36 @@ __bam_dup_convert(dbc, h, indx)
if (sz < dbp->pgsize / 4)
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. */
if ((ret = __db_new(dbc,
dbp->dup_compare == NULL ? P_LRECNO : P_LDUP, &dp)) != 0)
@ -739,8 +801,8 @@ __bam_dup_convert(dbc, h, indx)
* we're dealing with.
*/
memset(&hdr, 0, sizeof(hdr));
dindx = first;
indx = first;
first = indx;
dindx = indx;
cpindx = 0;
do {
/* Move cursors referencing the old entry to the new entry. */

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* 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"
@ -58,7 +58,7 @@ __bam_split_recover(dbenv, dbtp, lsnp, op, info)
_lp = lp = np = pp = _rp = rp = 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
@ -96,21 +96,21 @@ redo: if (DB_REDO(op)) {
REC_FGET(mpf, root_pgno, &pp, do_left);
cmp =
log_compare(&LSN(pp), &LSN(argp->pg.data));
CHECK_LSN(op,
CHECK_LSN(dbenv, op,
cmp, &LSN(pp), &LSN(argp->pg.data));
p_update = cmp == 0;
}
do_left: if (lp != NULL) {
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)
l_update = 1;
}
if (rp != NULL) {
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)
r_update = 1;
}
@ -211,7 +211,7 @@ check_next: /*
goto done;
}
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) {
PREV_PGNO(np) = argp->right;
np->lsn = *lsnp;
@ -337,12 +337,13 @@ __bam_rsplit_recover(dbenv, dbtp, lsnp, op, info)
DB_MPOOLFILE *mpf;
PAGE *pagep;
db_pgno_t pgno, root_pgno;
db_recno_t rcnt;
int cmp_n, cmp_p, modified, ret;
pagep = NULL;
COMPQUIET(info, NULL);
REC_PRINT(__bam_rsplit_print);
REC_INTRO(__bam_rsplit_read, 1);
REC_INTRO(__bam_rsplit_read, 1, 1);
/* Fix the root page. */
pgno = root_pgno = argp->root_pgno;
@ -361,10 +362,19 @@ __bam_rsplit_recover(dbenv, dbtp, lsnp, op, info)
modified = 0;
cmp_n = log_compare(lsnp, &LSN(pagep));
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)) {
/* 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);
if (LEVEL(pagep) > LEAFLEVEL)
RE_NREC_SET(pagep, rcnt);
pagep->pgno = root_pgno;
pagep->lsn = *lsnp;
modified = 1;
@ -403,7 +413,7 @@ do_page:
(void)__ua_memcpy(&copy_lsn, &LSN(argp->pgdbt.data), sizeof(DB_LSN));
cmp_n = log_compare(lsnp, &LSN(pagep));
cmp_p = log_compare(&LSN(pagep), &copy_lsn);
CHECK_LSN(op, cmp_p, &LSN(pagep), &copy_lsn);
CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &copy_lsn);
if (cmp_p == 0 && DB_REDO(op)) {
/* Need to redo update described. */
pagep->lsn = *lsnp;
@ -450,7 +460,7 @@ __bam_adj_recover(dbenv, dbtp, lsnp, op, info)
pagep = NULL;
COMPQUIET(info, NULL);
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. */
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
@ -468,7 +478,7 @@ __bam_adj_recover(dbenv, dbtp, lsnp, op, info)
modified = 0;
cmp_n = log_compare(lsnp, &LSN(pagep));
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)) {
/* Need to redo update described. */
if ((ret = __bam_adjindx(dbc,
@ -524,7 +534,7 @@ __bam_cadjust_recover(dbenv, dbtp, lsnp, op, info)
pagep = NULL;
COMPQUIET(info, NULL);
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. */
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
@ -542,7 +552,7 @@ __bam_cadjust_recover(dbenv, dbtp, lsnp, op, info)
modified = 0;
cmp_n = log_compare(lsnp, &LSN(pagep));
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)) {
/* Need to redo update described. */
if (IS_BTREE_PAGE(pagep)) {
@ -613,7 +623,7 @@ __bam_cdel_recover(dbenv, dbtp, lsnp, op, info)
pagep = NULL;
COMPQUIET(info, NULL);
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. */
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
@ -631,7 +641,7 @@ __bam_cdel_recover(dbenv, dbtp, lsnp, op, info)
modified = 0;
cmp_n = log_compare(lsnp, &LSN(pagep));
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)) {
/* Need to redo update described. */
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);
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;
modified = 1;
@ -689,7 +701,7 @@ __bam_repl_recover(dbenv, dbtp, lsnp, op, info)
pagep = NULL;
COMPQUIET(info, NULL);
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. */
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
@ -708,7 +720,7 @@ __bam_repl_recover(dbenv, dbtp, lsnp, op, info)
modified = 0;
cmp_n = log_compare(lsnp, &LSN(pagep));
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)) {
/*
* Need to redo update described.
@ -799,7 +811,7 @@ __bam_root_recover(dbenv, dbtp, lsnp, op, info)
meta = NULL;
COMPQUIET(info, NULL);
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 != DB_PAGE_NOTFOUND
@ -816,7 +828,7 @@ __bam_root_recover(dbenv, dbtp, lsnp, op, info)
modified = 0;
cmp_n = log_compare(lsnp, &LSN(meta));
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)) {
/* Need to redo update described. */
meta->root = argp->root_pgno;
@ -866,7 +878,7 @@ __bam_curadj_recover(dbenv, dbtp, lsnp, op, info)
COMPQUIET(mpf, NULL);
REC_PRINT(__bam_curadj_print);
REC_INTRO(__bam_curadj_read, 0);
REC_INTRO(__bam_curadj_read, 0, 1);
ret = 0;
if (op != DB_TXN_ABORT)
@ -891,8 +903,9 @@ __bam_curadj_recover(dbenv, dbtp, lsnp, op, info)
break;
case DB_CA_SPLIT:
__bam_ca_undosplit(file_dbp, argp->from_pgno,
argp->to_pgno, argp->left_pgno, argp->from_indx);
if ((ret = __bam_ca_undosplit(file_dbp, argp->from_pgno,
argp->to_pgno, argp->left_pgno, argp->from_indx)) != 0)
goto out;
break;
}
@ -928,7 +941,7 @@ __bam_rcuradj_recover(dbenv, dbtp, lsnp, op, info)
rdbc = NULL;
REC_PRINT(__bam_rcuradj_print);
REC_INTRO(__bam_rcuradj_read, 0);
REC_INTRO(__bam_rcuradj_read, 0, 1);
ret = t_ret = 0;
@ -1008,7 +1021,7 @@ __bam_relink_recover(dbenv, dbtp, lsnp, op, info)
pagep = NULL;
COMPQUIET(info, NULL);
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
@ -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
* elsewhere, so all we need do is recover the next page.
*/
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 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 = __memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
if (ret != DB_PAGE_NOTFOUND
#ifndef HAVE_FTRUNCATE
|| DB_REDO(op)
@ -1062,24 +1044,24 @@ next2: if ((ret = __memp_fget(mpf, &argp->next, 0, &pagep)) != 0) {
modified = 0;
cmp_n = log_compare(lsnp, &LSN(pagep));
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)) {
/* Redo the remove or undo the add. */
pagep->prev_pgno = argp->prev;
/* Redo the remove or replace. */
if (argp->new_pgno == PGNO_INVALID)
pagep->prev_pgno = argp->prev;
else
pagep->prev_pgno = argp->new_pgno;
pagep->lsn = *lsnp;
modified = 1;
} 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->lsn = argp->lsn_next;
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)
goto out;
pagep = NULL;
@ -1098,24 +1080,24 @@ prev: if ((ret = __memp_fget(mpf, &argp->prev, 0, &pagep)) != 0) {
modified = 0;
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)) {
/* 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;
} else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
/* Undo the relink. */
pagep->next_pgno = argp->pgno;
pagep->lsn = argp->lsn_prev;
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)
goto out;
pagep = NULL;
@ -1127,3 +1109,281 @@ out: if (pagep != NULL)
(void)__memp_fput(mpf, pagep, 0);
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;
}

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1998-2004
* Copyright (c) 1998-2005
* 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"
@ -69,7 +69,8 @@ __bam_truncate(dbc, countp)
ret = __bam_traverse(dbc,
DB_LOCK_WRITE, dbc->internal->root, __db_truncate_callback, &trunc);
*countp = trunc.count;
if (countp != NULL)
*countp = trunc.count;
return (ret);
}

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1997-2004
* Copyright (c) 1997-2005
* 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"
@ -203,7 +203,6 @@ __ram_c_del(dbc)
DB *dbp;
DB_LSN lsn;
DBT hdr, data;
EPG *epg;
int exact, ret, stack, t_ret;
dbp = dbc->dbp;
@ -280,21 +279,11 @@ __ram_c_del(dbc)
* are closed, and then clean it up.
*/
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
* 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
@ -764,7 +753,7 @@ __ram_ca(dbc_arg, op)
*/
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().
*/
@ -780,7 +769,7 @@ __ram_ca(dbc_arg, op)
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
MUTEX_LOCK(dbenv, dbp->mutex);
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
cp = (BTREE_CURSOR *)dbc->internal;
@ -789,7 +778,7 @@ __ram_ca(dbc_arg, op)
order <= cp->order)
order = cp->order + 1;
}
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
MUTEX_UNLOCK(dbenv, dbp->mutex);
}
} else
order = INVALID_ORDER;
@ -798,7 +787,7 @@ __ram_ca(dbc_arg, op)
for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
ldbp = LIST_NEXT(ldbp, dblistlinks)) {
MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
MUTEX_LOCK(dbenv, dbp->mutex);
for (dbc = TAILQ_FIRST(&ldbp->active_queue);
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
cp = (BTREE_CURSOR *)dbc->internal;
@ -868,9 +857,9 @@ iafter: if (!adjusted && C_LESSTHAN(cp_arg, cp)) {
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);
}
@ -1037,6 +1026,18 @@ __ram_writeback(dbp)
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. */
if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0)
return (ret);
@ -1064,7 +1065,7 @@ __ram_writeback(dbp)
*/
if ((ret =
__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.
@ -1082,18 +1083,6 @@ __ram_writeback(dbp)
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,
* and the pad character if we're doing fixed-length records.

View file

@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* Sleepycat Software. All rights reserved.
*/
/*
@ -36,7 +36,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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"
@ -100,44 +100,14 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
*
* 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);
}
/*
* 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)(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;
}
if ((ret = __bam_get_root(dbc, cp->root, stop, flags, &stack)) != 0)
return (ret);
lock_mode = cp->csp->lock_mode;
lock = cp->csp->lock;
h = cp->csp->page;
BT_STK_CLR(cp);
/*
* If appending to the tree, set the record number now -- we have the
* root page locked.
@ -260,15 +230,15 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
}
--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) {
/* 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,
cp, h, indx, lock, lock_mode, ret);
if (ret != 0)
@ -286,8 +256,8 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
* never unlock it.
*/
if ((LF_ISSET(S_PARENT) &&
(u_int8_t)(stop + 1) >= (u_int8_t)(h->level - 1)) ||
(h->level - 1) == LEAFLEVEL)
(u_int8_t)(stop + 1) >= (u_int8_t)(LEVEL(h) - 1)) ||
(LEVEL(h) - 1) == LEAFLEVEL)
stack = 1;
if ((ret = __memp_fput(mpf, h, 0)) != 0)

View file

@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* Sleepycat Software. All rights reserved.
*/
/*
@ -39,7 +39,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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"
@ -57,6 +57,102 @@
#include "dbinc/lock.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 --
* Search a btree for a key.
@ -65,12 +161,12 @@
* PUBLIC: const DBT *, u_int32_t, int, db_recno_t *, int *));
*/
int
__bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
__bam_search(dbc, root_pgno, key, flags, slevel, recnop, exactp)
DBC *dbc;
db_pgno_t root_pgno;
const DBT *key;
u_int32_t flags;
int stop, *exactp;
int slevel, *exactp;
db_recno_t *recnop;
{
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,
* if we're modifying record numbers, we have to lock the entire tree
* 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);
}
/*
* 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)(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;
}
if (root_pgno == PGNO_INVALID)
root_pgno = cp->root;
if ((ret = __bam_get_root(dbc, root_pgno, slevel, flags, &stack)) != 0)
return (ret);
lock_mode = cp->csp->lock_mode;
lock = cp->csp->lock;
h = cp->csp->page;
BT_STK_CLR(cp);
/* Choose a comparison function. */
func = F_ISSET(dbc, DBC_OPD) ?
@ -168,6 +217,23 @@ try_again:
for (;;) {
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
* 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
* match on a leaf page, we're done.
*/
adjust = TYPE(h) == P_LBTREE ? P_INDX : O_INDX;
for (base = 0,
lim = NUM_ENT(h) / (db_indx_t)adjust; lim != 0; lim >>= 1) {
indx = base + ((lim >> 1) * adjust);
@ -183,8 +248,13 @@ try_again:
__bam_cmp(dbp, key, h, indx, func, &cmp)) != 0)
goto err;
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 next;
}
if (cmp > 0) {
@ -197,10 +267,12 @@ try_again:
* No match found. Base is the smallest index greater than
* 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.
*/
if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP) {
if (LEVEL(h) == LEAFLEVEL ||
(!LF_ISSET(S_START) && LEVEL(h) == slevel)) {
*exactp = 0;
if (LF_ISSET(S_EXACT)) {
@ -218,6 +290,43 @@ try_again:
ret = t_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
* calling routine.
*/
if (LF_ISSET(S_DEL) && cp->csp == cp->sp)
cp->csp++;
BT_STK_ENTER(dbp->dbenv,
cp, h, base, lock, lock_mode, ret);
if (ret != 0)
@ -252,8 +363,12 @@ next: if (recnop != NULL)
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 (stop == h->level) {
if (slevel == LEVEL(h)) {
BT_STK_NUM(dbp->dbenv, cp, h, indx, ret);
if ((t_ret =
__LPUT(dbc, lock)) != 0 && ret == 0)
@ -278,13 +393,24 @@ next: if (recnop != NULL)
}
} else if (stack) {
/* 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,
cp, h, indx, lock, lock_mode, ret);
if (ret != 0)
goto err;
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,
cp, h, indx, lock, lock_mode, ret);
if (ret != 0)
@ -302,16 +428,69 @@ next: if (recnop != NULL)
* unlock it.
*/
if ((LF_ISSET(S_PARENT) &&
(u_int8_t)(stop + 1) >= (u_int8_t)(h->level - 1)) ||
(h->level - 1) == LEAFLEVEL)
(u_int8_t)(slevel + 1) >= (LEVEL(h) - 1)) ||
(LEVEL(h) - 1) == LEAFLEVEL)
stack = 1;
if ((ret = __memp_fput(mpf, h, 0)) != 0)
goto err;
h = NULL;
/*
* Returning a subtree. See if we have hit the start
* 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 &&
LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ;
if ((LF_ISSET(S_DEL) && NUM_ENT(h) == 1)) {
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,
LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) {
/*
@ -320,6 +499,8 @@ next: if (recnop != NULL)
* descending the tree holding read-locks.
*/
(void)__LPUT(dbc, lock);
if (LF_ISSET(S_DEL | S_NEXT))
cp->csp++;
goto err;
}
}
@ -340,12 +521,12 @@ found: *exactp = 1;
* all duplicate sets that are not on overflow pages exist on a
* single leaf page.
*/
if (TYPE(h) == P_LBTREE) {
if (TYPE(h) == P_LBTREE && NUM_ENT(h) > P_INDX) {
if (LF_ISSET(S_DUPLAST))
while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
inp[indx] == inp[indx + P_INDX])
indx += P_INDX;
else
else if (LF_ISSET(S_DUPFIRST))
while (indx > 0 &&
inp[indx] == inp[indx - P_INDX])
indx -= P_INDX;
@ -406,8 +587,11 @@ found: *exactp = 1;
ret = t_ret;
if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
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);
}
if (ret != 0)
goto err;
@ -471,6 +655,13 @@ __bam_stkrel(dbc, flags)
*/
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 ((t_ret = __LPUT(dbc, epg->lock)) != 0 && ret == 0)
ret = t_ret;
@ -480,7 +671,8 @@ __bam_stkrel(dbc, flags)
}
/* Clear the stack, all pages have been released. */
BT_STK_CLR(cp);
if (!LF_ISSET(STK_PGONLY))
BT_STK_CLR(cp);
return (ret);
}

View file

@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* Sleepycat Software. All rights reserved.
*/
/*
@ -36,7 +36,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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"
@ -56,7 +56,6 @@
static int __bam_broot __P((DBC *, PAGE *, PAGE *, PAGE *));
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_root __P((DBC *, EPG *));
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
* 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;
/*
@ -349,7 +348,7 @@ __bam_page(dbc, pp, cp)
* a page that's not in our direct ancestry. Consider a cursor walking
* 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
* 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.
*/
if (ISLEAF(cp->page) && NEXT_PGNO(cp->page) != PGNO_INVALID) {
@ -685,13 +684,15 @@ __ram_root(dbc, rootp, lp, rp)
/*
* __bam_pinsert --
* Insert a new key into a parent page, completing the split.
*
* PUBLIC: int __bam_pinsert __P((DBC *, EPG *, PAGE *, PAGE *, int));
*/
static int
__bam_pinsert(dbc, parent, lchild, rchild, space_check)
int
__bam_pinsert(dbc, parent, lchild, rchild, flags)
DBC *dbc;
EPG *parent;
PAGE *lchild, *rchild;
int space_check;
int flags;
{
BINTERNAL bi, *child_bi;
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. */
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
@ -750,7 +751,7 @@ __bam_pinsert(dbc, parent, lchild, rchild, space_check)
if (P_FREESPACE(dbp, ppage) < nbytes)
return (DB_NEEDSPLIT);
if (space_check)
if (LF_ISSET(BPI_SPACEONLY))
return (0);
/* 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);
switch (B_TYPE(child_bk->type)) {
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
* callback but no prefix compression callback. But,
* 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
* prefix compression callback that corresponds to its
* 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 (dbp->dup_compare == __bam_defcmp)
@ -800,13 +813,8 @@ __bam_pinsert(dbc, parent, lchild, rchild, space_check)
func = NULL;
} else
func = t->bt_prefix;
nbytes = BINTERNAL_PSIZE(child_bk->len);
nksize = child_bk->len;
if (func == NULL)
goto noprefix;
if (ppage->prev_pgno == PGNO_INVALID && off <= 1)
goto noprefix;
tmp_bk = GET_BKEYDATA(dbp, lchild, NUM_ENT(lchild) -
(TYPE(lchild) == P_LDUP ? O_INDX : P_INDX));
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)
nbytes = n;
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);
if (space_check)
if (LF_ISSET(BPI_SPACEONLY))
return (0);
memset(&bi, 0, sizeof(bi));
@ -849,7 +857,7 @@ noprefix: nksize = child_bk->len;
if (P_FREESPACE(dbp, ppage) < nbytes)
return (DB_NEEDSPLIT);
if (space_check)
if (LF_ISSET(BPI_SPACEONLY))
return (0);
memset(&bi, 0, sizeof(bi));
@ -883,7 +891,7 @@ noprefix: nksize = child_bk->len;
if (P_FREESPACE(dbp, ppage) < nbytes)
return (DB_NEEDSPLIT);
if (space_check)
if (LF_ISSET(BPI_SPACEONLY))
return (0);
/* 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
* 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. */
if (DBC_LOGGING(dbc)) {
if ((ret = __bam_cadjust_log(dbp, dbc->txn,
&LSN(ppage), 0, PGNO(ppage),
&LSN(ppage), parent->indx, -(int32_t)nrecs, 0)) != 0)
return (ret);
if ((ret = __bam_cadjust_log(dbp, dbc->txn,
&LSN(ppage), 0, PGNO(ppage), &LSN(ppage),
parent->indx, -(int32_t)nrecs, 0)) != 0)
return (ret);
} else
LSN_NOT_LOGGED(LSN(ppage));

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* 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"
@ -155,7 +155,6 @@ meta_only:
/* Get metadata page statistics. */
sp->bt_metaflags = meta->dbmeta.flags;
sp->bt_maxkey = meta->maxkey;
sp->bt_minkey = meta->minkey;
sp->bt_re_len = meta->re_len;
sp->bt_re_pad = meta->re_pad;
@ -246,16 +245,12 @@ __bam_stat_print(dbc, flags)
}
__db_msg(dbenv, "%s\tByte order", s);
__db_prflags(dbenv, NULL, sp->bt_metaflags, fn, NULL, "\tFlags");
if (dbp->type == DB_BTREE) {
#ifdef NOT_IMPLEMENTED
__db_dl(dbenv, "Maximum keys per-page", (u_long)sp->bt_maxkey);
#endif
if (dbp->type == DB_BTREE)
__db_dl(dbenv, "Minimum keys per-page", (u_long)sp->bt_minkey);
}
if (dbp->type == DB_RECNO) {
__db_dl(dbenv,
"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);
}
__db_dl(dbenv,

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* 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"

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1999-2004
* Copyright (c) 1999-2005
* 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"
@ -89,10 +89,8 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags)
} else
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) */
pip->re_pad = meta->re_pad;
pip->re_len = meta->re_len;
/*
@ -1618,8 +1616,17 @@ bad_prev: isbad = 1;
if (relenp)
*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;
}
if (isbad == 0 && level != child_level + 1) {
isbad = 1;
EPRINT((dbenv,
@ -2037,38 +2044,36 @@ __bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
DBT *key;
u_int32_t flags;
{
DBT dbt, unkdbt;
DB_ENV *dbenv;
BKEYDATA *bk;
BOVERFLOW *bo;
DBT dbt, unknown_key, unknown_data;
DB_ENV *dbenv;
VRFY_ITEM *pgmap;
db_indx_t i, beg, end, *inp;
db_indx_t i, last, beg, end, *inp;
u_int32_t himark;
void *ovflbuf;
int t_ret, ret, err_ret;
int ret, t_ret, t2_ret;
dbenv = dbp->dbenv;
/* Shut up lint. */
COMPQUIET(end, 0);
ovflbuf = pgmap = NULL;
err_ret = ret = 0;
inp = P_INP(dbp, h);
memset(&dbt, 0, sizeof(DBT));
dbt.flags = DB_DBT_REALLOC;
memset(&unkdbt, 0, sizeof(DBT));
unkdbt.size = (u_int32_t)(strlen("UNKNOWN") + 1);
unkdbt.data = "UNKNOWN";
memset(&unknown_key, 0, sizeof(DBT));
unknown_key.size = (u_int32_t)strlen("UNKNOWN_KEY");
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;
* __db_safe_goff will realloc as needed.
*/
if ((ret = __os_malloc(dbenv, dbp->pgsize, &ovflbuf)) != 0)
return (ret);
goto err;
if (LF_ISSET(DB_AGGRESSIVE) && (ret =
__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.
*
* If we're salvaging normally, loop from 0 through NUM_ENT(h).
* If we're being aggressive, loop until we hit the end of the page--
* If we're salvaging normally, loop from 0 through NUM_ENT(h). If
* we're being aggressive, loop until we hit the end of the page --
* NUM_ENT() may be bogus.
*/
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 (!LF_ISSET(DB_AGGRESSIVE) && i >= NUM_ENT(h))
break;
/* Verify the current item. */
ret = __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) {
t_ret =
__db_vrfy_inpitem(dbp, h, pgno, i, 1, flags, &himark, NULL);
if (t_ret != 0) {
/*
* 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 this is a btree leaf and we've printed out a key
* but not its associated data item, fix this imbalance
* by printing an "UNKNOWN_DATA".
*/
ret = (i < NUM_ENT(h)) ? DB_VERIFY_BAD : 0;
break;
if (pgtype == P_LBTREE && i % P_INDX == 1 &&
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)
* try to fetch.
*
* We only print deleted items if DB_AGGRESSIVE is set.
*/
if (ret == 0) {
/*
* We only want to print deleted items if
* DB_AGGRESSIVE is set.
*/
bk = GET_BKEYDATA(dbp, h, i);
if (!LF_ISSET(DB_AGGRESSIVE) && B_DISSET(bk->type))
continue;
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
* key is non-NULL, we're a dup page, so we've got to
* print the key first, unless SA_SKIPFIRSTKEY is set
* and we're on the first entry.
*/
if (key != NULL &&
(i != 0 || !LF_ISSET(SA_SKIPFIRSTKEY)))
if ((ret = __db_vrfy_prdbt(key,
0, " ", handle, callback, 0, vdp)) != 0)
err_ret = ret;
/*
* If this is a btree leaf and we're about to print out a data
* item for which we didn't print out a key, fix this imbalance
* by printing an "UNKNOWN_KEY".
*/
if (pgtype == P_LBTREE && i % P_INDX == 1 &&
last != i - 1 && (t_ret = __db_vrfy_prdbt(
&unknown_key, 0, " ", handle, callback, 0, vdp)) != 0) {
if (ret == 0)
ret = t_ret;
goto err;
}
last = i;
beg = inp[i];
switch (B_TYPE(bk->type)) {
case B_DUPLICATE:
end = beg + BOVERFLOW_SIZE - 1;
/*
* If we're not on a normal btree leaf page,
* there shouldn't be off-page
* dup sets. Something's confused; just
* drop it, and the code to pick up unlinked
* offpage dup sets will print it out
* with key "UNKNOWN" later.
*/
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);
/*
* We're going to go try to print the next item. If key is
* non-NULL, we're a dup page, so we've got to print the key
* first, unless SA_SKIPFIRSTKEY is set and we're on the first
* entry.
*/
if (key != NULL && (i != 0 || !LF_ISSET(SA_SKIPFIRSTKEY)))
if ((t_ret = __db_vrfy_prdbt(key,
0, " ", handle, callback, 0, vdp)) != 0) {
if (ret == 0)
ret = t_ret;
goto err;
}
beg = inp[i];
switch (B_TYPE(bk->type)) {
case B_DUPLICATE:
end = beg + BOVERFLOW_SIZE - 1;
/*
* 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 we're not on a normal btree leaf page, there
* shouldn't be off-page dup sets. Something's
* confused; just drop it, and the code to pick up
* unlinked offpage dup sets will print it out
* with key "UNKNOWN" later.
*/
if (LF_ISSET(DB_AGGRESSIVE)) {
pgmap[beg] = VRFY_ITEM_BEGIN;
pgmap[end] = VRFY_ITEM_END;
if (pgtype != P_LBTREE)
break;
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)
__os_free(dbenv, pgmap);
__os_free(dbenv, ovflbuf);
if (ovflbuf != NULL)
__os_free(dbenv, ovflbuf);
/* Mark this page as done. */
if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0)
return (t_ret);
if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0)
ret = t_ret;
return ((err_ret != 0) ? err_ret : ret);
return (ret);
}
/*

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Copyright (c) 1996-2005
* 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
@ -210,10 +210,10 @@ END
BEGIN relink 147
/* Fileid of db affected. */
DB fileid int32_t ld
/* The page being changed. */
/* The page being removed. */
ARG pgno db_pgno_t lu
/* The page's original lsn. */
POINTER lsn DB_LSN * lu
/* The new page number, if any. */
ARG new_pgno db_pgno_t lu
/* The previous page. */
ARG prev db_pgno_t lu
/* The previous page's original lsn. */
@ -223,3 +223,30 @@ ARG next db_pgno_t lu
/* The previous page's original lsn. */
POINTER lsn_next DB_LSN * lu
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

View file

@ -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>

View file

@ -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);
}

View file

@ -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.

View file

@ -21,12 +21,15 @@ Package=<4>
Project_Dep_Name db_deadlock
End Project Dependency
Begin Project Dependency
Project_Dep_Name DB_DLL
Project_Dep_Name db_dll
End Project Dependency
Begin Project Dependency
Project_Dep_Name db_dump
End Project Dependency
Begin Project Dependency
Project_Dep_Name db_hotbackup
End Project Dependency
Begin Project Dependency
Project_Dep_Name db_load
End Project Dependency
Begin Project Dependency
@ -45,7 +48,7 @@ Package=<4>
Project_Dep_Name db_verify
End Project Dependency
Begin Project Dependency
Project_Dep_Name DB_Static
Project_Dep_Name db_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name ex_access
@ -63,9 +66,18 @@ Package=<4>
Project_Dep_Name ex_mpool
End Project Dependency
Begin Project Dependency
Project_Dep_Name ex_sequence
End Project Dependency
Begin Project Dependency
Project_Dep_Name ex_tpcb
End 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
End Project Dependency
Begin Project Dependency
@ -81,10 +93,31 @@ Package=<4>
Project_Dep_Name excxx_mpool
End Project Dependency
Begin Project Dependency
Project_Dep_Name excxx_sequence
End Project Dependency
Begin Project Dependency
Project_Dep_Name excxx_tpcb
End 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
}}}
@ -99,7 +132,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -114,7 +147,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -129,7 +162,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name DB_DLL
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -156,7 +189,22 @@ Package=<5>
Package=<4>
{{{
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
}}}
@ -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>
{{{
Begin Project Dependency
Project_Dep_Name db_dll
End Project Dependency
Begin Project Dependency
Project_Dep_Name db_static
End Project Dependency
}}}
###############################################################################
@ -204,7 +234,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -219,7 +249,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -234,12 +264,24 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
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>
Package=<5>
@ -249,7 +291,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -276,7 +318,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name DB_DLL
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -309,7 +351,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -324,7 +366,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -339,7 +381,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -354,7 +396,58 @@ Package=<5>
Package=<4>
{{{
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
}}}
@ -369,7 +462,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -384,7 +477,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -399,7 +492,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -414,7 +507,22 @@ Package=<5>
Package=<4>
{{{
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
}}}
@ -429,7 +537,67 @@ Package=<5>
Package=<4>
{{{
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
}}}
@ -444,7 +612,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -459,7 +627,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -474,7 +642,37 @@ Package=<5>
Package=<4>
{{{
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
}}}
@ -489,7 +687,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name db_lib
Project_Dep_Name db_dll
End Project Dependency
}}}
@ -504,7 +702,22 @@ Package=<5>
Package=<4>
{{{
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
}}}
@ -519,7 +732,37 @@ Package=<5>
Package=<4>
{{{
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
}}}

View file

@ -4,7 +4,7 @@
# 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 use the Export Makefile command and run
!MESSAGE
@ -13,14 +13,18 @@ CFG=@project_name@ - Win32 Debug Static
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static"
!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!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 Release Static" (based on "Win32 (x86) Console Application")
!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Console Application")
!MESSAGE "@project_name@ - Win32 ASCII Debug" (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
# Begin Project
@ -34,99 +38,207 @@ RSC=rc.exe
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Output_Dir "@bin_rel_dest@"
# PROP BASE Intermediate_Dir "Release/@project_name@"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Output_Dir "@bin_rel_dest@"
# PROP Intermediate_Dir "Release/@project_name@"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /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" @extra_cppflags@ /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt"
# ADD BASE LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.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@"
@POST_BUILD@
!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Output_Dir "@bin_debug_dest@"
# PROP BASE Intermediate_Dir "Debug/@project_name@"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Output_Dir "@bin_debug_dest@"
# PROP Intermediate_Dir "Debug/@project_name@"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /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" @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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no
# ADD BASE LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# 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_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Output_Dir "@bin_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 "Release_static"
# PROP Intermediate_Dir "Release_static"
# PROP Output_Dir "@bin_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 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /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 /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /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 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.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 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_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Output_Dir "@bin_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 "Debug_static"
# PROP Intermediate_Dir "Debug_static"
# PROP Output_Dir "@bin_debug_dest@_AMD64"
# PROP Intermediate_Dir "Debug_AMD64/@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" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MTd /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 /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 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 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 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 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
@ -134,8 +246,12 @@ LINK32=link.exe
# Name "@project_name@ - Win32 Release"
# Name "@project_name@ - Win32 Debug"
# Name "@project_name@ - Win32 Release Static"
# Name "@project_name@ - Win32 Debug Static"
# 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@
# Begin Source File

View file

@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1999-2004
* Copyright (c) 1999-2005
* 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 -

View file

@ -19,6 +19,12 @@ CFG=@project_name@ - Win32 Debug
!MESSAGE
!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 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
# Begin Project
@ -33,17 +39,17 @@ RSC=rc.exe
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Output_Dir "@lib_rel_dest@"
# PROP BASE Intermediate_Dir "Release/@project_name@"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Output_Dir "@lib_rel_dest@"
# PROP Intermediate_Dir "Release/@project_name@"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /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 "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 MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@ -52,24 +58,25 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll"
# ADD BASE LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
# 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"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Output_Dir "@lib_debug_dest@"
# PROP BASE Intermediate_Dir "Debug/@project_name@"
# PROP BASE Target_Dir ""
# PROP Use_MFC 2
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Output_Dir "@lib_debug_dest@"
# PROP Intermediate_Dir "Debug/@project_name@"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /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 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 "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
# ADD BASE 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 BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 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 BASE LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# 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
@ -88,6 +269,13 @@ LINK32=link.exe
# Name "@project_name@ - Win32 Release"
# 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@
# End Target
# End Project

View file

@ -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'
EXPORTS

Some files were not shown because too many files have changed in this diff Show more