aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/os_unix.c31
-rw-r--r--src/resolve.c2
-rw-r--r--src/test_regexp.c28
-rw-r--r--src/where.c2
4 files changed, 33 insertions, 30 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index 315f15018..dc13be186 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -412,11 +412,7 @@ static struct unix_syscall {
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
aSyscall[13].pCurrent)
-#if SQLITE_ENABLE_LOCKING_STYLE
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
-#else
- { "fchmod", (sqlite3_syscall_ptr)0, 0 },
-#endif
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
@@ -441,9 +437,6 @@ static struct unix_syscall {
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
- { "umask", (sqlite3_syscall_ptr)umask, 0 },
-#define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
-
}; /* End of the overrideable system calls */
/*
@@ -548,14 +541,7 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
*/
static int robust_open(const char *z, int f, mode_t m){
int fd;
- mode_t m2;
- mode_t origM = 0;
- if( m==0 ){
- m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
- }else{
- m2 = m;
- origM = osUmask(0);
- }
+ mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
do{
#if defined(O_CLOEXEC)
fd = osOpen(z,f|O_CLOEXEC,m2);
@@ -563,12 +549,17 @@ static int robust_open(const char *z, int f, mode_t m){
fd = osOpen(z,f,m2);
#endif
}while( fd<0 && errno==EINTR );
- if( m ){
- osUmask(origM);
- }
+ if( fd>=0 ){
+ if( m!=0 ){
+ struct stat statbuf;
+ if( osFstat(fd, &statbuf)==0 && (statbuf.st_mode&0777)!=m ){
+ osFchmod(fd, m);
+ }
+ }
#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
- if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
+ osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
#endif
+ }
return fd;
}
@@ -6994,7 +6985,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==22 );
+ assert( ArraySize(aSyscall)==21 );
/* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
diff --git a/src/resolve.c b/src/resolve.c
index 944fb5cad..aeeec8837 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -647,7 +647,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
pNC->nErr++;
is_agg = 0;
- }else if( no_such_func ){
+ }else if( no_such_func && pParse->db->init.busy==0 ){
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
pNC->nErr++;
}else if( wrong_num_args ){
diff --git a/src/test_regexp.c b/src/test_regexp.c
index 87fb3db5b..c0361f17d 100644
--- a/src/test_regexp.c
+++ b/src/test_regexp.c
@@ -129,7 +129,7 @@ static unsigned re_next_char(ReInput *p){
unsigned c;
if( p->i>=p->mx ) return 0;
c = p->z[p->i++];
- if( c>0x80 ){
+ if( c>=0x80 ){
if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){
c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
if( c<0x80 ) c = 0xfffd;
@@ -137,13 +137,13 @@ static unsigned re_next_char(ReInput *p){
&& (p->z[p->i+1]&0xc0)==0x80 ){
c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
p->i += 2;
- if( c<0x3ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
+ if( c<=0x3ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
}else if( (c&0xf8)==0xf0 && p->i+3<p->mx && (p->z[p->i]&0xc0)==0x80
&& (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
| (p->z[p->i+2]&0x3f);
p->i += 3;
- if( c<0xffff ) c = 0xfffd;
+ if( c<=0xffff || c>0x10ffff ) c = 0xfffd;
}else{
c = 0xfffd;
}
@@ -169,7 +169,7 @@ static int re_digit_char(int c){
/* Return true if c is a perl "space" character: [ \t\r\n\v\f] */
static int re_space_char(int c){
- return c==' ' || c=='\t' || c=='\n' || c=='\v' || c=='\f';
+ return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
}
/* Run a compiled regular expression on the zero-terminated input
@@ -188,7 +188,9 @@ int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
in.z = zIn;
in.i = 0;
- in.mx = nIn>=0 ? nIn : strlen((char*)zIn);
+ in.mx = nIn>=0 ? nIn : strlen((char const*)zIn);
+
+ /* Look for the initial prefix match, if there is one. */
if( pRe->nInit ){
unsigned char x = pRe->zInit[0];
while( in.i+pRe->nInit<=in.mx
@@ -198,6 +200,7 @@ int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
}
if( in.i+pRe->nInit>in.mx ) return 0;
}
+
if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
pToFree = 0;
aStateSet[0].aState = aSpace;
@@ -385,8 +388,8 @@ static unsigned re_esc_char(ReCompiled *p){
if( p->sIn.i>=p->sIn.mx ) return 0;
c = p->sIn.z[p->sIn.i];
if( c=='u' && p->sIn.i+5<p->sIn.mx ){
- v = 0;
const unsigned char *zIn = p->sIn.z + p->sIn.i;
+ v = 0;
if( re_hex(zIn[1],&v)
&& re_hex(zIn[2],&v)
&& re_hex(zIn[3],&v)
@@ -624,7 +627,7 @@ const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
}
pRe->sIn.z = (unsigned char*)zIn;
pRe->sIn.i = 0;
- pRe->sIn.mx = strlen((char*)pRe->sIn.z);
+ pRe->sIn.mx = strlen(zIn);
zErr = re_subcompile_re(pRe);
if( zErr ){
re_free(pRe);
@@ -641,6 +644,15 @@ const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
re_free(pRe);
return "unrecognized character";
}
+
+ /* The following is a performance optimization. If the regex begins with
+ ** ".*" (if the input regex lacks an initial "^") and afterwards there are
+ ** one or more matching characters, enter those matching characters into
+ ** zInit[]. The re_match() routine can then search ahead in the input
+ ** string looking for the initial match without having to run the whole
+ ** regex engine over the string. Do not worry able trying to match
+ ** unicode characters beyond plane 0 - those are very rare and this is
+ ** just an optimization. */
if( pRe->aOp[0]==RE_OP_ANYSTAR ){
for(j=0, i=1; j<sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
unsigned x = pRe->aArg[i];
@@ -652,7 +664,7 @@ const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
}else if( x<=0xffff ){
pRe->zInit[j++] = 0xd0 | (x>>12);
pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
- pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
+ pRe->zInit[j++] = 0x80 | (x&0x3f);
}else{
break;
}
diff --git a/src/where.c b/src/where.c
index 3b64b411d..6e096e5c6 100644
--- a/src/where.c
+++ b/src/where.c
@@ -3302,7 +3302,7 @@ static void bestBtreeIndex(WhereBestIdx *p){
pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev);
WHERETRACE((" --> after isSortingIndex: bRev=%d nOBSat=%d\n",
bRev, pc.plan.nOBSat));
- if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_UNIQUE)!=0 ){
+ if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
pc.plan.wsFlags |= WHERE_ORDERED;
}
if( nOrderBy==pc.plan.nOBSat ){