summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/attach.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/attach.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/attach.c83
1 files changed, 53 insertions, 30 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/attach.c b/ext/pdo_sqlite/sqlite/src/attach.c
index 10abc49014..473a6c5992 100644
--- a/ext/pdo_sqlite/sqlite/src/attach.c
+++ b/ext/pdo_sqlite/sqlite/src/attach.c
@@ -15,6 +15,7 @@
*/
#include "sqliteInt.h"
+#ifndef SQLITE_OMIT_ATTACH
/*
** Resolve an expression that was part of an ATTACH or DETACH statement. This
** is slightly different from resolving a normal SQL expression, because simple
@@ -39,6 +40,10 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
if( pExpr ){
if( pExpr->op!=TK_ID ){
rc = sqlite3ExprResolveNames(pName, pExpr);
+ if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
+ sqlite3ErrorMsg(pName->pParse, "invalid name: \"%T\"", &pExpr->span);
+ return SQLITE_ERROR;
+ }
}else{
pExpr->op = TK_STRING;
}
@@ -68,8 +73,8 @@ static void attachFunc(
const char *zName;
const char *zFile;
Db *aNew;
- char zErr[128];
char *zErrDyn = 0;
+ char zErr[128];
zFile = (const char *)sqlite3_value_text(argv[0]);
zName = (const char *)sqlite3_value_text(argv[1]);
@@ -82,20 +87,23 @@ static void attachFunc(
** * Transaction currently open
** * Specified database name already being used.
*/
- if( db->nDb>=MAX_ATTACHED+2 ){
+ if( db->nDb>=SQLITE_MAX_ATTACHED+2 ){
sqlite3_snprintf(
- sizeof(zErr), zErr, "too many attached databases - max %d", MAX_ATTACHED
+ sizeof(zErr), zErr, "too many attached databases - max %d",
+ SQLITE_MAX_ATTACHED
);
goto attach_error;
}
if( !db->autoCommit ){
- strcpy(zErr, "cannot ATTACH database within transaction");
+ sqlite3_snprintf(sizeof(zErr), zErr,
+ "cannot ATTACH database within transaction");
goto attach_error;
}
for(i=0; i<db->nDb; i++){
char *z = db->aDb[i].zName;
if( z && zName && sqlite3StrICmp(z, zName)==0 ){
- sqlite3_snprintf(sizeof(zErr), zErr, "database %s is already in use", zName);
+ sqlite3_snprintf(sizeof(zErr), zErr,
+ "database %s is already in use", zName);
goto attach_error;
}
}
@@ -104,14 +112,16 @@ static void attachFunc(
** hash tables.
*/
if( db->aDb==db->aDbStatic ){
- aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
+ aNew = sqlite3_malloc( sizeof(db->aDb[0])*3 );
if( aNew==0 ){
+ db->mallocFailed = 1;
return;
}
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
}else{
- aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
+ aNew = sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
if( aNew==0 ){
+ db->mallocFailed = 1;
return;
}
}
@@ -123,23 +133,26 @@ static void attachFunc(
** it to obtain the database schema. At this point the schema may
** or may not be initialised.
*/
- rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
+ rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
+ db->openFlags | SQLITE_OPEN_MAIN_DB,
+ &aNew->pBt);
if( rc==SQLITE_OK ){
- aNew->pSchema = sqlite3SchemaGet(aNew->pBt);
+ aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
if( !aNew->pSchema ){
rc = SQLITE_NOMEM;
}else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
- strcpy(zErr,
+ sqlite3_snprintf(sizeof(zErr), zErr,
"attached databases must use the same text encoding as main database");
goto attach_error;
}
+ sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode);
}
- aNew->zName = sqliteStrDup(zName);
+ aNew->zName = sqlite3DbStrDup(db, zName);
aNew->safety_level = 3;
#if SQLITE_HAS_CODEC
{
- extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
+ extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
int nKey;
char *zKey;
@@ -147,7 +160,7 @@ static void attachFunc(
switch( t ){
case SQLITE_INTEGER:
case SQLITE_FLOAT:
- zErrDyn = sqliteStrDup("Invalid key value");
+ zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
rc = SQLITE_ERROR;
break;
@@ -173,9 +186,11 @@ static void attachFunc(
** we found it.
*/
if( rc==SQLITE_OK ){
- sqlite3SafetyOn(db);
+ (void)sqlite3SafetyOn(db);
+ sqlite3BtreeEnterAll(db);
rc = sqlite3Init(db, &zErrDyn);
- sqlite3SafetyOff(db);
+ sqlite3BtreeLeaveAll(db);
+ (void)sqlite3SafetyOff(db);
}
if( rc ){
int iDb = db->nDb - 1;
@@ -187,8 +202,8 @@ static void attachFunc(
}
sqlite3ResetInternalSchema(db, 0);
db->nDb = iDb;
- if( rc==SQLITE_NOMEM ){
- if( !sqlite3MallocFailed() ) sqlite3FailedMalloc();
+ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+ db->mallocFailed = 1;
sqlite3_snprintf(sizeof(zErr),zErr, "out of memory");
}else{
sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile);
@@ -202,11 +217,12 @@ attach_error:
/* Return an error if we get here */
if( zErrDyn ){
sqlite3_result_error(context, zErrDyn, -1);
- sqliteFree(zErrDyn);
+ sqlite3_free(zErrDyn);
}else{
zErr[sizeof(zErr)-1] = 0;
sqlite3_result_error(context, zErr, -1);
}
+ if( rc ) sqlite3_result_error_code(context, rc);
}
/*
@@ -244,7 +260,8 @@ static void detachFunc(
goto detach_error;
}
if( !db->autoCommit ){
- strcpy(zErr, "cannot DETACH database within transaction");
+ sqlite3_snprintf(sizeof(zErr), zErr,
+ "cannot DETACH database within transaction");
goto detach_error;
}
if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){
@@ -281,16 +298,17 @@ static void codeAttach(
Vdbe *v;
FuncDef *pFunc;
sqlite3* db = pParse->db;
+ int regArgs;
#ifndef SQLITE_OMIT_AUTHORIZATION
- assert( sqlite3MallocFailed() || pAuthArg );
+ assert( db->mallocFailed || pAuthArg );
if( pAuthArg ){
- char *zAuthArg = sqlite3NameFromToken(&pAuthArg->span);
+ char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span);
if( !zAuthArg ){
goto attach_end;
}
rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
- sqliteFree(zAuthArg);
+ sqlite3_free(zAuthArg);
if(rc!=SQLITE_OK ){
goto attach_end;
}
@@ -310,21 +328,23 @@ static void codeAttach(
}
v = sqlite3GetVdbe(pParse);
- sqlite3ExprCode(pParse, pFilename);
- sqlite3ExprCode(pParse, pDbname);
- sqlite3ExprCode(pParse, pKey);
+ regArgs = sqlite3GetTempRange(pParse, 3);
+ sqlite3ExprCode(pParse, pFilename, regArgs);
+ sqlite3ExprCode(pParse, pDbname, regArgs+1);
+ sqlite3ExprCode(pParse, pKey, regArgs+2);
- assert( v || sqlite3MallocFailed() );
+ assert( v || db->mallocFailed );
if( v ){
- sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
+ sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-nFunc, regArgs);
+ sqlite3VdbeChangeP5(v, nFunc);
pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
- sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);
+ sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
/* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
** statement only). For DETACH, set it to false (expire all existing
** statements).
*/
- sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0);
+ sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
}
attach_end:
@@ -350,14 +370,17 @@ void sqlite3Detach(Parse *pParse, Expr *pDbname){
void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);
}
+#endif /* SQLITE_OMIT_ATTACH */
/*
** Register the functions sqlite_attach and sqlite_detach.
*/
void sqlite3AttachFunctions(sqlite3 *db){
+#ifndef SQLITE_OMIT_ATTACH
static const int enc = SQLITE_UTF8;
sqlite3CreateFunc(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0);
sqlite3CreateFunc(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0);
+#endif
}
/*
@@ -412,7 +435,7 @@ int sqlite3FixSrcList(
zDb = pFix->zDb;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->zDatabase==0 ){
- pItem->zDatabase = sqliteStrDup(zDb);
+ pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
}else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",