diff --git a/extra/mkkeywordhash.c b/extra/mkkeywordhash.c index 2ad74eddcb7732cad93a3fea0cfe486d6d47fd34..b83294cb385257faa0ac8d507b486ffc07597fd9 100644 --- a/extra/mkkeywordhash.c +++ b/extra/mkkeywordhash.c @@ -55,41 +55,17 @@ struct Keyword { */ #define ALTER 0x00000001 #define ALWAYS 0x00000002 -#ifdef SQL_OMIT_AUTOINCREMENT -# define AUTOINCR 0 -#else # define AUTOINCR 0x00000010 -#endif -#ifdef SQL_OMIT_CAST -# define CAST 0 -#else # define CAST 0x00000020 -#endif -#ifdef SQL_OMIT_COMPOUND_SELECT -# define COMPOUND 0 -#else # define COMPOUND 0x00000040 -#endif -#ifdef SQL_OMIT_CONFLICT_CLAUSE -# define CONFLICT 0 -#else # define CONFLICT 0x00000080 -#endif #define EXPLAIN 0x00000100 #define FKEY 0x00000200 -#ifdef SQL_OMIT_PRAGMA -# define PRAGMA 0 -#else # define PRAGMA 0x00000400 -#endif #define SUBQUERY 0x00001000 # define TRIGGER 0x00002000 # define VIEW 0x00008000 -#ifdef SQL_OMIT_CTE -# define CTE 0 -#else # define CTE 0x00040000 -#endif # define RESERVED 0x00000001 /* ** These are the keywords diff --git a/src/box/sql/CMakeLists.txt b/src/box/sql/CMakeLists.txt index b9dbe141adc700233c7df28f831b4fb384d51fba..7059b57cf55ca368253797f24c23020266a02647 100644 --- a/src/box/sql/CMakeLists.txt +++ b/src/box/sql/CMakeLists.txt @@ -10,7 +10,6 @@ set(SQL_BIN_DIR ${CMAKE_BINARY_DIR}/src/box/sql) include_directories(${SQL_SRC_DIR}) include_directories(${SQL_BIN_DIR}) -add_definitions(-DSQL_MAX_WORKER_THREADS=0) add_definitions(-DSQL_OMIT_AUTOMATIC_INDEX) set(TEST_DEFINITIONS diff --git a/src/box/sql/build.c b/src/box/sql/build.c index d98ccadc5cde92dfd85c95dc3e991cffd5f9c939..4a6a9a327bc0e8b3f99fe3061f596b26483a1767 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -3226,7 +3226,6 @@ sqlHaltConstraint(Parse * pParse, /* Parsing context */ sqlVdbeChangeP5(v, p5Errmsg); } -#ifndef SQL_OMIT_CTE /* * This routine is invoked once per CTE by the parser while parsing a * WITH clause. @@ -3307,8 +3306,6 @@ sqlWithDelete(sql * db, With * pWith) } } -#endif /* !defined(SQL_OMIT_CTE) */ - int vdbe_emit_halt_with_presence_test(struct Parse *parser, int space_id, int index_id, int key_reg, uint32_t key_len, diff --git a/src/box/sql/cursor.h b/src/box/sql/cursor.h index 23741161349d92bbc06ae44019b34df7e4d73865..e5c49d73661995ab73091e36926fea2e98f29c4d 100644 --- a/src/box/sql/cursor.h +++ b/src/box/sql/cursor.h @@ -101,29 +101,4 @@ int sqlCursorIsValidNN(BtCursor *); #define CURSOR_INVALID 0 #define CURSOR_VALID 1 -/* - * Routines to read or write a two- and four-byte big-endian integer values. - */ -#define get2byte(x) ((x)[0]<<8 | (x)[1]) -#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) -#define get4byte sqlGet4byte -#define put4byte sqlPut4byte - -/* - * get2byteAligned(), unlike get2byte(), requires that its argument point to a - * two-byte aligned address. get2bytea() is only used for accessing the - * cell addresses in a btree header. - */ -#if SQL_BYTEORDER==4321 -#define get2byteAligned(x) (*(u16*)(x)) -#elif SQL_BYTEORDER==1234 && !defined(SQL_DISABLE_INTRINSIC) \ - && GCC_VERSION>=4008000 -#define get2byteAligned(x) __builtin_bswap16(*(u16*)(x)) -#elif SQL_BYTEORDER==1234 && !defined(SQL_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 -#define get2byteAligned(x) _byteswap_ushort(*(u16*)(x)) -#else -#define get2byteAligned(x) ((x)[0]<<8 | (x)[1]) -#endif - #endif /* SQL_CURSOR_H */ diff --git a/src/box/sql/date.c b/src/box/sql/date.c index 07a57ab2a96a9135ccbe142b0a763b64aec94371..26afd18d8148208dab3d02846235841f831f4c22 100644 --- a/src/box/sql/date.c +++ b/src/box/sql/date.c @@ -550,18 +550,18 @@ osLocaltime(time_t * t, struct tm *pTm) #if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S struct tm *pX; pX = localtime(t); -#ifndef SQL_UNTESTABLE + if (sqlGlobalConfig.bLocaltimeFault) pX = 0; -#endif + if (pX) *pTm = *pX; rc = pX == 0; #else -#ifndef SQL_UNTESTABLE + if (sqlGlobalConfig.bLocaltimeFault) return 1; -#endif + #if HAVE_LOCALTIME_R rc = localtime_r(t, pTm) == 0; #else diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index 40b677a0151c846ab906e311f6915c264c59147d..a8a984404c65abbb0e73cfc9d8fdffcf5251f7a1 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -1502,7 +1502,6 @@ sql_expr_dup(struct sql *db, struct Expr *p, int flags, char **buffer) * argument. If an OOM condition is encountered, NULL is returned * and the db->mallocFailed flag set. */ -#ifndef SQL_OMIT_CTE static With * withDup(sql * db, With * p) { @@ -1525,9 +1524,6 @@ withDup(sql * db, With * p) } return pRet; } -#else -#define withDup(x,y) 0 -#endif /* * The following group of routines make deep copies of expressions, @@ -2574,20 +2570,6 @@ sqlFindInIndex(Parse * pParse, /* Parsing context */ parts[0].sort_order; if (prRhsHasNull) { -#ifdef SQL_ENABLE_COLUMN_USED_MASK - i64 mask = - (1 << nExpr) - 1; - sqlVdbeAddOp4Dup8(v, - OP_ColumnsUsed, - iTab, - 0, - 0, - (u8 - *) - & - mask, - P4_INT64); -#endif *prRhsHasNull = ++pParse->nMem; if (nExpr == 1) { /* Tarantool: Check for null is performed on first key of the index. */ @@ -3061,18 +3043,6 @@ sqlExprCodeIN(Parse * pParse, /* Parsing and code generating context */ assert(pParse->is_aborted || nVector == 1 || eType == IN_INDEX_EPH || eType == IN_INDEX_INDEX_ASC || eType == IN_INDEX_INDEX_DESC); -#ifdef SQL_DEBUG - /* Confirm that aiMap[] contains nVector integer values between 0 and - * nVector-1. - */ - /* - for(i=0; i<nVector; i++){ - int j, cnt; - for(cnt=j=0; j<nVector; j++) if( aiMap[j]==i ) cnt++; - assert( cnt==1 ); - } - */ -#endif /* Code the LHS, the <expr> from "<expr> IN (...)". If the LHS is a * vector, then it is stored in an array of nVector registers starting @@ -3087,17 +3057,6 @@ sqlExprCodeIN(Parse * pParse, /* Parsing and code generating context */ rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy); /* Tarantoool: Order is always preserved. */ rLhs = rLhsOrig; - /* for(i=0; i<nVector && aiMap[i]==i; i++){} /\* Are LHS fields reordered? *\/ */ - /* if( i==nVector ){ */ - /* /\* LHS fields are not reordered *\/ */ - /* rLhs = rLhsOrig; */ - /* }else{ */ - /* /\* Need to reorder the LHS fields according to aiMap *\/ */ - /* rLhs = sqlGetTempRange(pParse, nVector); */ - /* for(i=0; i<nVector; i++){ */ - /* sqlVdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0); */ - /* } */ - /* } */ /* If sqlFindInIndex() did not find or create an index that is * suitable for evaluating the IN operator, then evaluate using a @@ -3601,7 +3560,7 @@ sqlExprCodeMove(Parse * pParse, int iFrom, int iTo, int nReg) sqlExprCacheRemove(pParse, iFrom, nReg); } -#if defined(SQL_DEBUG) || defined(SQL_COVERAGE_TEST) +#if defined(SQL_DEBUG) /* * Return true if any register in the range iFrom..iTo (inclusive) * is used as part of the column cache. @@ -3621,7 +3580,7 @@ usedAsColumnCache(Parse * pParse, int iFrom, int iTo) } return 0; } -#endif /* SQL_DEBUG || SQL_COVERAGE_TEST */ +#endif /* SQL_DEBUG */ /* * Convert a scalar expression node to a TK_REGISTER referencing @@ -3813,7 +3772,7 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target) case TK_REGISTER:{ return pExpr->iTable; } -#ifndef SQL_OMIT_CAST + case TK_CAST:{ /* Expressions of the form: CAST(pLeft AS token) */ inReg = @@ -3827,7 +3786,7 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target) sql_expr_type_cache_change(pParse, inReg, 1); return inReg; } -#endif /* SQL_OMIT_CAST */ + case TK_LT: case TK_LE: case TK_GT: @@ -3997,12 +3956,6 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target) assert(!ExprHasProperty(pExpr, EP_IntValue)); zId = pExpr->u.zToken; pDef = sqlFindFunction(db, zId, nFarg, 0); -#ifdef SQL_ENABLE_UNKNOWN_SQL_FUNCTION - if (pDef == 0 && pParse->explain) { - pDef = - sqlFindFunction(db, "unknown", nFarg, 0); - } -#endif if (pDef == 0 || pDef->xFinalize != 0) { diag_set(ClientError, ER_NO_SUCH_FUNCTION, zId); @@ -4500,21 +4453,6 @@ sqlExprCode(Parse * pParse, Expr * pExpr, int target) } } -/* - * Make a transient copy of expression pExpr and then code it using - * sqlExprCode(). This routine works just like sqlExprCode() - * except that the input expression is guaranteed to be unchanged. - */ -void -sqlExprCodeCopy(Parse * pParse, Expr * pExpr, int target) -{ - sql *db = pParse->db; - pExpr = sqlExprDup(db, pExpr, 0); - if (!db->mallocFailed) - sqlExprCode(pParse, pExpr, target); - sql_expr_delete(db, pExpr, false); -} - /* * Generate code that will evaluate expression pExpr and store the * results in register target. The results are guaranteed to appear @@ -5628,27 +5566,3 @@ sqlClearTempRegCache(Parse * pParse) pParse->nRangeReg = 0; } -/* - * Validate that no temporary register falls within the range of - * iFirst..iLast, inclusive. This routine is only call from within assert() - * statements. - */ -#ifdef SQL_DEBUG -int -sqlNoTempsInRange(Parse * pParse, int iFirst, int iLast) -{ - int i; - if (pParse->nRangeReg > 0 - && pParse->iRangeReg + pParse->nRangeReg < iLast - && pParse->iRangeReg >= iFirst) { - return 0; - } - for (i = 0; i < pParse->nTempReg; i++) { - if (pParse->aTempReg[i] >= iFirst - && pParse->aTempReg[i] <= iLast) { - return 0; - } - } - return 1; -} -#endif /* SQL_DEBUG */ diff --git a/src/box/sql/fault.c b/src/box/sql/fault.c index 8ee774e4c666f083d6a9e1611940712878537531..26eeaeedb1c833b68788c0b626fe312433e90ad6 100644 --- a/src/box/sql/fault.c +++ b/src/box/sql/fault.c @@ -47,8 +47,6 @@ #include "sqlInt.h" -#ifndef SQL_UNTESTABLE - /* * Global variables. */ @@ -104,4 +102,3 @@ sqlEndBenignMalloc(void) } } -#endif /* #ifndef SQL_UNTESTABLE */ diff --git a/src/box/sql/func.c b/src/box/sql/func.c index bb7405e683b9163b9e919f81893296c9ee846e54..054865830a3c2b30c21a247ddaf3f8f4a5954049 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -429,16 +429,6 @@ substrFunc(sql_context * context, int argc, sql_value ** argv) if (p1 < 0) len = sql_utf8_char_count(z, sql_value_bytes(argv[0])); } -#ifdef SQL_SUBSTR_COMPATIBILITY - /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as - * as substr(X,1,N) - it returns the first N characters of X. This - * is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] - * from 2009-02-02 for compatibility of applications that exploited the - * old buggy behavior. - */ - if (p1 == 0) - p1 = 1; /* <rdar://problem/6778339> */ -#endif if (argc == 3) { p2 = sql_value_int(argv[2]); if (p2 < 0) { @@ -1491,23 +1481,6 @@ trim_func_three_args(struct sql_context *context, int argc, sql_value **argv) sql_free(char_len); } -#ifdef SQL_ENABLE_UNKNOWN_SQL_FUNCTION -/* - * The "unknown" function is automatically substituted in place of - * any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN - * when the SQL_ENABLE_UNKNOWN_FUNCTION compile-time option is used. - * When the "sql" command-line shell is built using this functionality, - * that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries - * involving application-defined functions to be examined in a generic - * sql shell. - */ -static void -unknownFunc(sql_context * context, int argc, sql_value ** argv) -{ - /* no-op */ -} -#endif /*SQL_ENABLE_UNKNOWN_SQL_FUNCTION */ - /* IMP: R-25361-16150 This function is omitted from sql by default. It * is only available if the SQL_SOUNDEX compile-time option is used * when sql is built. @@ -1977,9 +1950,6 @@ sqlRegisterBuiltinFunctions(void) FIELD_TYPE_INTEGER), LIKEFUNC(like, 3, 1, SQL_FUNC_LIKE, FIELD_TYPE_INTEGER), -#ifdef SQL_ENABLE_UNKNOWN_SQL_FUNCTION - FUNCTION(unknown, -1, 0, 0, unknownFunc, 0), -#endif FUNCTION(coalesce, 1, 0, 0, 0, FIELD_TYPE_SCALAR), FUNCTION(coalesce, 0, 0, 0, 0, FIELD_TYPE_SCALAR), FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQL_FUNC_COALESCE, diff --git a/src/box/sql/global.c b/src/box/sql/global.c index 9af671a5ed76ad5d1c0b3b3cc617d158bb247550..b6a01731b2b4fc4fd7a2178c844368b1ef6660cb 100644 --- a/src/box/sql/global.c +++ b/src/box/sql/global.c @@ -204,9 +204,7 @@ SQL_WSD struct sqlConfig sqlConfig = { 0, /* xVdbeBranch */ 0, /* pVbeBranchArg */ #endif -#ifndef SQL_UNTESTABLE 0, /* xTestCallback */ -#endif 0, /* bLocaltimeFault */ 0x7ffffffe /* iOnceResetThreshold */ }; @@ -246,7 +244,3 @@ int sqlPendingByte = 0x40000000; */ const unsigned char sqlOpcodeProperty[] = OPFLG_INITIALIZER; -/* - * Name of the default collating sequence - */ -const char sqlStrBINARY[] = "BINARY"; diff --git a/src/box/sql/hwtime.h b/src/box/sql/hwtime.h index 278a1bf1cfa87c7434661c2091d5264cc3d5b3db..f2196360b015ebddf365616f591ab185f208c1d1 100644 --- a/src/box/sql/hwtime.h +++ b/src/box/sql/hwtime.h @@ -43,34 +43,6 @@ * processor and returns that value. This can be used for high-res * profiling. */ -#if (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - -#if defined(__GNUC__) - -__inline__ sql_uint64 -sqlHwtime(void) -{ - unsigned int lo, hi; - __asm__ __volatile__("rdtsc":"=a"(lo), "=d"(hi)); - return (sql_uint64) hi << 32 | lo; -} - -#elif defined(_MSC_VER) - -__declspec(naked) -__inline sql_uint64 __cdecl -sqlHwtime(void) -{ - __asm { - rdtsc ret; - return value at EDX:EAX} -} - -#endif - -#elif (defined(__GNUC__) && defined(__x86_64__)) - __inline__ sql_uint64 sqlHwtime(void) { @@ -79,39 +51,4 @@ sqlHwtime(void) return val; } -#elif (defined(__GNUC__) && defined(__ppc__)) - -__inline__ sql_uint64 -sqlHwtime(void) -{ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b":"=r"(retval), "=r"(junk)); - return retval; -} - -#else - -#error Need implementation of sqlHwtime() for your platform. - - /* - * To compile without implementing sqlHwtime() for your platform, - * you can remove the above #error and use the following - * stub function. You will lose timing support for many - * of the debugging and testing utilities, but it should at - * least compile and run. - */ -sql_uint64 -sqlHwtime(void) -{ - return ((sql_uint64) 0); -} - -#endif - #endif /* !defined(SQL_HWTIME_H) */ diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c index 6a27f8307f67dcf58e77093170034a0fa2b85f98..6d70c51c2dabc5f8c972ea44e6c04c0b92c40bb5 100644 --- a/src/box/sql/insert.c +++ b/src/box/sql/insert.c @@ -321,7 +321,6 @@ sqlInsert(Parse * pParse, /* Parser context */ sqlVdbeCountChanges(v); sql_set_multi_write(pParse, pSelect != NULL || trigger != NULL); -#ifndef SQL_OMIT_XFER_OPT /* If the statement is of the form * * INSERT INTO <table1> SELECT * FROM <table2>; @@ -337,7 +336,6 @@ sqlInsert(Parse * pParse, /* Parser context */ assert(pList == 0); goto insert_end; } -#endif /* SQL_OMIT_XFER_OPT */ /* * Allocate registers for holding the tupleid of the new @@ -992,7 +990,6 @@ vdbe_emit_insertion_completion(struct Vdbe *v, struct space *space, sqlVdbeChangeP5(v, pik_flags); } -#ifndef SQL_OMIT_XFER_OPT /** * Check to see if index @src is compatible as a source of data * for index @dest in an insert transfer optimization. The rules @@ -1260,4 +1257,3 @@ xferOptimization(Parse * pParse, /* Parser context */ return 1; } } -#endif /* SQL_OMIT_XFER_OPT */ diff --git a/src/box/sql/main.c b/src/box/sql/main.c index fe1135a717c649be9e9826607398234a4139c02c..339b456dfdc0e02b43a7b36c1099c8c00c1d8266 100644 --- a/src/box/sql/main.c +++ b/src/box/sql/main.c @@ -40,16 +40,6 @@ #include "version.h" #include "box/session.h" -#if !defined(SQL_OMIT_TRACE) && defined(SQL_ENABLE_IOTRACE) -/* - * If the following function pointer is not NULL and if - * SQL_ENABLE_IOTRACE is enabled, then messages describing - * I/O active are written using this function. These messages - * are intended for debugging activity only. - */ -SQL_API void (SQL_CDECL * sqlIoTrace) (const char *, ...) = 0; -#endif - /* * If the following global variable points to a string which is the * name of a directory, then that directory will be used to store @@ -187,7 +177,6 @@ sql_initialize(void) static int setupLookaside(sql * db, void *pBuf, int sz, int cnt) { -#ifndef SQL_OMIT_LOOKASIDE void *pStart; if (db->lookaside.nOut) { return SQL_BUSY; @@ -241,7 +230,6 @@ setupLookaside(sql * db, void *pBuf, int sz, int cnt) db->lookaside.bDisable = 1; db->lookaside.bMalloced = 0; } -#endif /* SQL_OMIT_LOOKASIDE */ return SQL_OK; } @@ -513,65 +501,6 @@ sql_create_function_v2(sql * db, return rc; } -#ifndef SQL_OMIT_TRACE -/* Register a trace callback using the version-2 interface. - */ -int -sql_trace_v2(sql * db, /* Trace this connection */ - unsigned mTrace, /* Mask of events to be traced */ - int (*xTrace) (unsigned, void *, void *, void *), /* Callback to invoke */ - void *pArg) /* Context */ -{ - if (mTrace == 0) - xTrace = 0; - if (xTrace == 0) - mTrace = 0; - db->mTrace = mTrace; - db->xTrace = xTrace; - db->pTraceArg = pArg; - return SQL_OK; -} - -#endif /* SQL_OMIT_TRACE */ - -/* - * This function returns true if main-memory should be used instead of - * a temporary file for transient pager files and statement journals. - * The value returned depends on the value of db->temp_store (runtime - * parameter) and the compile time value of SQL_TEMP_STORE. The - * following table describes the relationship between these two values - * and this functions return value. - * - * SQL_TEMP_STORE db->temp_store Location of temporary database - * ----------------- -------------- ------------------------------ - * 0 any file (return 0) - * 1 1 file (return 0) - * 1 2 memory (return 1) - * 1 0 file (return 0) - * 2 1 file (return 0) - * 2 2 memory (return 1) - * 2 0 memory (return 1) - * 3 any memory (return 1) - */ -int -sqlTempInMemory(const sql * db) -{ -#if SQL_TEMP_STORE==1 - return (db->temp_store == 2); -#endif -#if SQL_TEMP_STORE==2 - return (db->temp_store != 1); -#endif -#if SQL_TEMP_STORE==3 - UNUSED_PARAMETER(db); - return 1; -#endif -#if SQL_TEMP_STORE<1 || SQL_TEMP_STORE>3 - UNUSED_PARAMETER(db); - return 0; -#endif -} - /* * Return the most recent error code generated by an sql routine. If NULL is * passed to this function, we assume a malloc() failed during sql_open(). @@ -604,7 +533,6 @@ static const int aHardLimit[] = { SQL_MAX_ATTACHED, SQL_MAX_LIKE_PATTERN_LENGTH, SQL_MAX_TRIGGER_DEPTH, - SQL_MAX_WORKER_THREADS, }; /* @@ -640,9 +568,6 @@ static const int aHardLimit[] = { #if SQL_MAX_TRIGGER_DEPTH<1 #error SQL_MAX_TRIGGER_DEPTH must be at least 1 #endif -#if SQL_MAX_WORKER_THREADS<0 || SQL_MAX_WORKER_THREADS>50 -#error SQL_MAX_WORKER_THREADS must be between 0 and 50 -#endif /* * Change the value of a limit. Report the old value. @@ -678,9 +603,6 @@ sql_limit(sql * db, int limitId, int newLimit) SQL_MAX_LIKE_PATTERN_LENGTH); assert(aHardLimit[SQL_LIMIT_TRIGGER_DEPTH] == SQL_MAX_TRIGGER_DEPTH); - assert(aHardLimit[SQL_LIMIT_WORKER_THREADS] == - SQL_MAX_WORKER_THREADS); - assert(SQL_LIMIT_WORKER_THREADS == (SQL_N_LIMIT - 1)); if (limitId < 0 || limitId >= SQL_N_LIMIT) { return -1; @@ -723,7 +645,6 @@ sql_init_db(sql **out_db) assert(sizeof(db->aLimit) == sizeof(aHardLimit)); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); - db->aLimit[SQL_LIMIT_WORKER_THREADS] = SQL_DEFAULT_WORKER_THREADS; db->aLimit[SQL_LIMIT_COMPOUND_SELECT] = SQL_DEFAULT_COMPOUND_SELECT; db->szMmap = sqlGlobalConfig.szMmap; db->nMaxSorterMmap = 0x7FFFFFFF; diff --git a/src/box/sql/malloc.c b/src/box/sql/malloc.c index d6f99b46e6d05af23f44574287d1cc22a6c012eb..831be177e6b7efa51b78f261f2d787ebf8ab261c 100644 --- a/src/box/sql/malloc.c +++ b/src/box/sql/malloc.c @@ -128,16 +128,12 @@ sql_sized_realloc(void *pPrior, int nByte) int sql_release_memory(int n) { -#ifdef SQL_ENABLE_MEMORY_MANAGEMENT - return sqlPcacheReleaseMemory(n); -#else /* IMPLEMENTATION-OF: R-34391-24921 The sql_release_memory() routine * is a no-op returning zero if sql is not compiled with * SQL_ENABLE_MEMORY_MANAGEMENT. */ UNUSED_PARAMETER(n); return 0; -#endif } /* @@ -253,15 +249,6 @@ sqlHeapNearlyFull(void) return mem0.nearlyFull; } -/* - * Deinitialize the memory allocation subsystem. - */ -void -sqlMallocEnd(void) -{ - memset(&mem0, 0, sizeof(mem0)); -} - /* * Return the amount of memory currently checked out. */ @@ -273,19 +260,6 @@ sql_memory_used(void) return res; } -/* - * Return the maximum amount of memory that has ever been - * checked out since either the beginning of this process - * or since the most recent reset. - */ -sql_int64 -sql_memory_highwater(int resetFlag) -{ - sql_int64 res, mx; - sql_status64(SQL_STATUS_MEMORY_USED, &res, &mx, resetFlag); - return mx; -} - /* * Trigger the alarm */ @@ -319,12 +293,6 @@ mallocWithAlarm(int n, void **pp) } } p = sql_sized_malloc(nFull); -#ifdef SQL_ENABLE_MEMORY_MANAGEMENT - if (p == 0 && mem0.alarmThreshold > 0) { - sqlMallocAlarm(nFull); - p = sql_sized_malloc(nFull); - } -#endif if (p) { nFull = sqlMallocSize(p); sqlStatusUp(SQL_STATUS_MEMORY_USED, nFull); @@ -376,118 +344,14 @@ sql_malloc64(sql_uint64 n) return sqlMalloc(n); } -/* - * Each thread may only have a single outstanding allocation from - * xScratchMalloc(). We verify this constraint in the single-threaded - * case by setting scratchAllocOut to 1 when an allocation - * is outstanding clearing it when the allocation is freed. - */ -#if !defined(NDEBUG) -static int scratchAllocOut = 0; -#endif - -/* - * Allocate memory that is to be used and released right away. - * This routine is similar to alloca() in that it is not intended - * for situations where the memory might be held long-term. This - * routine is intended to get memory to old large transient data - * structures that would not normally fit on the stack of an - * embedded processor. - */ -void * -sqlScratchMalloc(int n) -{ - void *p; - assert(n > 0); - - sqlStatusHighwater(SQL_STATUS_SCRATCH_SIZE, n); - if (mem0.nScratchFree && sqlGlobalConfig.szScratch >= n) { - p = mem0.pScratchFree; - mem0.pScratchFree = mem0.pScratchFree->pNext; - mem0.nScratchFree--; - sqlStatusUp(SQL_STATUS_SCRATCH_USED, 1); - } else { - p = sqlMalloc(n); - if (sqlGlobalConfig.bMemstat && p) { - sqlStatusUp(SQL_STATUS_SCRATCH_OVERFLOW, - sqlMallocSize(p)); - } - sqlMemdebugSetType(p, MEMTYPE_SCRATCH); - } - -#if !defined(NDEBUG) - /* EVIDENCE-OF: R-12970-05880 sql will not use more than one scratch - * buffers per thread. - * - * This can only be checked in single-threaded mode. - */ - assert(scratchAllocOut == 0); - if (p) - scratchAllocOut++; -#endif - - return p; -} - -void -sqlScratchFree(void *p) -{ - if (p) { - -#if !defined(NDEBUG) - /* Verify that no more than two scratch allocation per thread - * is outstanding at one time. (This is only checked in the - * single-threaded case since checking in the multi-threaded case - * would be much more complicated.) - */ - assert(scratchAllocOut >= 1 && scratchAllocOut <= 2); - scratchAllocOut--; -#endif - - if (SQL_WITHIN - (p, sqlGlobalConfig.pScratch, mem0.pScratchEnd)) { - /* Release memory from the SQL_CONFIG_SCRATCH allocation */ - ScratchFreeslot *pSlot; - pSlot = (ScratchFreeslot *) p; - pSlot->pNext = mem0.pScratchFree; - mem0.pScratchFree = pSlot; - mem0.nScratchFree++; - assert(mem0.nScratchFree <= - (u32) sqlGlobalConfig.nScratch); - sqlStatusDown(SQL_STATUS_SCRATCH_USED, 1); - } else { - /* Release memory back to the heap */ - assert(sqlMemdebugHasType(p, MEMTYPE_SCRATCH)); - assert(sqlMemdebugNoType - (p, (u8) ~ MEMTYPE_SCRATCH)); - sqlMemdebugSetType(p, MEMTYPE_HEAP); - if (sqlGlobalConfig.bMemstat) { - int iSize = sqlMallocSize(p); - sqlStatusDown - (SQL_STATUS_SCRATCH_OVERFLOW, iSize); - sqlStatusDown(SQL_STATUS_MEMORY_USED, - iSize); - sqlStatusDown(SQL_STATUS_MALLOC_COUNT, - 1); - sql_sized_free(p); - } else - sql_sized_free(p); - } - } -} - /* * TRUE if p is a lookaside memory allocation from db */ -#ifndef SQL_OMIT_LOOKASIDE static int isLookaside(sql * db, void *p) { return SQL_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd); } -#else -#define isLookaside(A,B) 0 -#endif /* * Return the size of a memory allocation previously obtained from @@ -521,14 +385,6 @@ sqlDbMallocSize(sql * db, void *p) return db->lookaside.sz; } -sql_uint64 -sql_msize(void *p) -{ - assert(sqlMemdebugNoType(p, (u8) ~ MEMTYPE_HEAP)); - assert(sqlMemdebugHasType(p, MEMTYPE_HEAP)); - return p ? sql_sized_sizeof(p) : 0; -} - /* * Free memory previously obtained from sqlMalloc(). */ @@ -645,14 +501,6 @@ sqlRealloc(void *pOld, u64 nBytes) * The public interface to sqlRealloc. Make sure that the memory * subsystem is initialized prior to invoking sqlRealloc. */ -void * -sql_realloc(void *pOld, int n) -{ - if (n < 0) - n = 0; /* IMP: R-26507-47431 */ - return sqlRealloc(pOld, n); -} - void * sql_realloc64(void *pOld, sql_uint64 n) { @@ -740,7 +588,6 @@ sqlDbMallocRaw(sql * db, u64 n) void * sqlDbMallocRawNN(sql * db, u64 n) { -#ifndef SQL_OMIT_LOOKASIDE LookasideSlot *pBuf; assert(db != 0); assert(db->pnBytesFreed == 0); @@ -762,13 +609,6 @@ sqlDbMallocRawNN(sql * db, u64 n) } else if (db->mallocFailed) { return 0; } -#else - assert(db != 0); - assert(db->pnBytesFreed == 0); - if (db->mallocFailed) { - return 0; - } -#endif return dbMallocRawFinish(db, n); } @@ -877,16 +717,6 @@ sqlDbStrNDup(sql * db, const char *z, u64 n) return zNew; } -/* - * Free any prior content in *pz and replace it with a copy of zNew. - */ -void -sqlSetString(char **pz, sql * db, const char *zNew) -{ - sqlDbFree(db, *pz); - *pz = sqlDbStrDup(db, zNew); -} - /* * Call this routine to record the fact that an OOM (out-of-memory) error * has happened. This routine will set db->mallocFailed, and also diff --git a/src/box/sql/os_unix.c b/src/box/sql/os_unix.c index 615d539b5ca364e8c6f892e5cab5219a4cc6d138..f9969b4470dcc3b58214e72e067443cf2401bb3c 100644 --- a/src/box/sql/os_unix.c +++ b/src/box/sql/os_unix.c @@ -1937,7 +1937,6 @@ unixDelete(sql_vfs * NotUsed, /* VFS containing this as the xDelete method */ } return rc; } -#ifndef SQL_DISABLE_DIRSYNC if ((dirSync & 1) != 0) { int fd; rc = openDirectory(zPath, &fd); @@ -1953,7 +1952,6 @@ unixDelete(sql_vfs * NotUsed, /* VFS containing this as the xDelete method */ rc = SQL_OK; } } -#endif return rc; } diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index bc577a580a1c33acd209beabe99c363322223c8d..7af5e7d5140dc1e5b70e5687ec9d2052babe71ce 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -229,9 +229,6 @@ columnname(A) ::= nm(A) typedef(Y). {sqlAddColumn(pParse,&A,&Y);} CONFLICT DEFERRED END FAIL IGNORE INITIALLY INSTEAD NO MATCH PLAN QUERY KEY OFFSET RAISE RELEASE REPLACE RESTRICT -%ifdef SQL_OMIT_COMPOUND_SELECT - INTERSECT -%endif SQL_OMIT_COMPOUND_SELECT RENAME CTIME_KW IF . %wildcard ANY. @@ -475,7 +472,7 @@ select(A) ::= with(W) selectnowith(X). { } selectnowith(A) ::= oneselect(A). -%ifndef SQL_OMIT_COMPOUND_SELECT + selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). { Select *pRhs = Z; Select *pLhs = A; @@ -502,7 +499,7 @@ selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). { multiselect_op(A) ::= UNION(OP). {A = @OP; /*A-overwrites-OP*/} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP; /*A-overwrites-OP*/} -%endif SQL_OMIT_COMPOUND_SELECT + oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y) groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { #ifdef SQL_DEBUG @@ -1036,7 +1033,7 @@ expr(A) ::= expr(A) COLLATE id(C). { A.pExpr = sqlExprAddCollateToken(pParse, A.pExpr, &C, 1); A.zEnd = &C.z[C.n]; } -%ifndef SQL_OMIT_CAST + expr(A) ::= CAST(X) LP expr(E) AS typedef(T) RP(Y). { spanSet(&A,&X,&Y); /*A-overwrites-X*/ A.pExpr = sql_expr_new_dequoted(pParse->db, TK_CAST, NULL); @@ -1047,7 +1044,6 @@ expr(A) ::= CAST(X) LP expr(E) AS typedef(T) RP(Y). { A.pExpr->type = T.type; sqlExprAttachSubtrees(pParse->db, A.pExpr, E.pExpr, 0); } -%endif SQL_OMIT_CAST expr(A) ::= TRIM(X) LP trim_operands(Y) RP(E). { A.pExpr = sqlExprFunction(pParse, Y, &X); @@ -1721,7 +1717,6 @@ cmd ::= ALTER TABLE fullname(X) DROP CONSTRAINT nm(Z). { %destructor wqlist {sqlWithDelete(pParse->db, $$);} with(A) ::= . {A = 0;} -%ifndef SQL_OMIT_CTE with(A) ::= WITH wqlist(W). { A = W; } with(A) ::= WITH RECURSIVE wqlist(W). { A = W; } @@ -1731,7 +1726,6 @@ wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. { wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. { A = sqlWithAdd(pParse, A, &X, Y, Z); } -%endif SQL_OMIT_CTE ////////////////////////////// TYPE DECLARATION /////////////////////////////// %type typedef {struct type_def} diff --git a/src/box/sql/printf.c b/src/box/sql/printf.c index 31d21dbb0cc6483210e17115d52198dc0f7e469b..a397b90d8af272a3ad43acf3b04fddcc61db070e 100644 --- a/src/box/sql/printf.c +++ b/src/box/sql/printf.c @@ -293,11 +293,6 @@ sqlVXPrintf(StrAccum * pAccum, /* Accumulate results here */ width = wx & 0x7fffffff; } assert(width >= 0); -#ifdef SQL_PRINTF_PRECISION_LIMIT - if (width > SQL_PRINTF_PRECISION_LIMIT) { - width = SQL_PRINTF_PRECISION_LIMIT; - } -#endif /* Get the precision */ if (c == '.') { @@ -327,11 +322,6 @@ sqlVXPrintf(StrAccum * pAccum, /* Accumulate results here */ precision = -1; } assert(precision >= (-1)); -#ifdef SQL_PRINTF_PRECISION_LIMIT - if (precision > SQL_PRINTF_PRECISION_LIMIT) { - precision = SQL_PRINTF_PRECISION_LIMIT; - } -#endif /* Get the conversion type modifier */ if (c == 'l') { diff --git a/src/box/sql/random.c b/src/box/sql/random.c index 9e1122b227a00ba748a3bde45ffe44cd6673f084..78dc27293b3cb0cda22b1cd5f00b6c7f83cde22f 100644 --- a/src/box/sql/random.c +++ b/src/box/sql/random.c @@ -107,29 +107,3 @@ sql_randomness(int N, void *pBuf) *(zBuf++) = wsdPrng.s[t]; } while (--N); } - -#ifndef SQL_UNTESTABLE -/* - * For testing purposes, we sometimes want to preserve the state of - * PRNG and restore the PRNG to its saved state at a later time, or - * to reset the PRNG to its initial state. These routines accomplish - * those tasks. - */ -static SQL_WSD struct sqlPrngType sqlSavedPrng; -void -sqlPrngSaveState(void) -{ - memcpy(&GLOBAL(struct sqlPrngType, sqlSavedPrng), - &GLOBAL(struct sqlPrngType, sqlPrng), sizeof(sqlPrng) - ); -} - -void -sqlPrngRestoreState(void) -{ - memcpy(&GLOBAL(struct sqlPrngType, sqlPrng), - &GLOBAL(struct sqlPrngType, sqlSavedPrng), - sizeof(sqlPrng) - ); -} -#endif /* SQL_UNTESTABLE */ diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c index ac85b85a95fa05f2d23a584e564d095d04bdef81..d65f74410f96e991b867e957cf34778e0dc25671 100644 --- a/src/box/sql/resolve.c +++ b/src/box/sql/resolve.c @@ -674,11 +674,7 @@ resolveExprStep(Walker * pWalker, Expr * pExpr) pParse->is_aborted = true; pNC->nErr++; is_agg = 0; - } else if (no_such_func && pParse->db->init.busy == 0 -#ifdef SQL_ENABLE_UNKNOWN_SQL_FUNCTION - && pParse->explain == 0 -#endif - ) { + } else if (no_such_func && pParse->db->init.busy == 0) { diag_set(ClientError, ER_NO_SUCH_FUNCTION, zId); pParse->is_aborted = true; pNC->nErr++; diff --git a/src/box/sql/select.c b/src/box/sql/select.c index 22aa628308f85c1ef21693befd65fb65a7084216..05385f9a13c026d53fddc50432ab3ef0954ae12d 100644 --- a/src/box/sql/select.c +++ b/src/box/sql/select.c @@ -1136,7 +1136,6 @@ selectInnerLoop(Parse * pParse, /* The parser context */ /* In this mode, write each query result to the key of the temporary * table iParm. */ -#ifndef SQL_OMIT_COMPOUND_SELECT case SRT_Union:{ int r1; r1 = sqlGetTempReg(pParse); @@ -1156,7 +1155,6 @@ selectInnerLoop(Parse * pParse, /* The parser context */ nResultCol); break; } -#endif /* SQL_OMIT_COMPOUND_SELECT */ /* Store the result as data using a unique key. */ @@ -1173,7 +1171,7 @@ selectInnerLoop(Parse * pParse, /* The parser context */ nResultCol, r1 + nPrefixReg); /* Set flag to save memory allocating one by malloc. */ sqlVdbeChangeP5(v, 1); -#ifndef SQL_OMIT_CTE + if (eDest == SRT_DistFifo) { /* If the destination is DistFifo, then cursor (iParm+1) is open * on an ephemeral index. If the current row is already present @@ -1189,7 +1187,7 @@ selectInnerLoop(Parse * pParse, /* The parser context */ pDest->reg_eph + 1); assert(pSort == 0); } -#endif + if (pSort) { pushOntoSorter(pParse, pSort, p, r1 + nPrefixReg, regResult, 1, @@ -1292,7 +1290,6 @@ selectInnerLoop(Parse * pParse, /* The parser context */ break; } -#ifndef SQL_OMIT_CTE /* Write the results into a priority queue that is order according to * pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an * index with pSO->nExpr+2 columns. Build a key using pSO for the first @@ -1343,7 +1340,6 @@ selectInnerLoop(Parse * pParse, /* The parser context */ sqlReleaseTempRange(pParse, r2, nKey + 2); break; } -#endif /* SQL_OMIT_CTE */ /* Discard the results. This is used for SELECT statements inside * the body of a TRIGGER. The purpose of such selects is to call @@ -1516,7 +1512,6 @@ explainTempTable(Parse * pParse, const char *zUsage) } } -#if !defined(SQL_OMIT_COMPOUND_SELECT) /* * Unless an "EXPLAIN QUERY PLAN" command is being processed, this function * is a no-op. Otherwise, it adds a single row of output to the EQP result, @@ -1554,10 +1549,6 @@ explainComposite(Parse * pParse, /* Parse context */ P4_DYNAMIC); } } -#else -/* No-op versions of the explainXXX() functions and macros. */ -#define explainComposite(v,w,x,y,z) -#endif /* * If the inner loop was generated using a non-null pOrderBy argument, @@ -2185,7 +2176,6 @@ computeLimitRegisters(Parse * pParse, Select * p, int iBreak) } } -#ifndef SQL_OMIT_COMPOUND_SELECT /** * This function determines resulting collation sequence for * @n-th column of the result set for the compound SELECT @@ -2298,7 +2288,6 @@ sql_multiselect_orderby_to_key_info(struct Parse *parse, struct Select *s, return key_info; } -#ifndef SQL_OMIT_CTE /* * This routine generates VDBE code to compute the content of a WITH RECURSIVE * query of the form: @@ -2478,7 +2467,6 @@ generateWithRecursiveQuery(Parse * pParse, /* Parsing context */ p->pOffset = pOffset; return; } -#endif /* SQL_OMIT_CTE */ /* Forward references */ static int multiSelectOrderBy(Parse * pParse, /* Parsing context */ @@ -2637,11 +2625,9 @@ multiSelect(Parse * pParse, /* Parsing context */ assert(p->pEList && pPrior->pEList); assert(p->pEList->nExpr == pPrior->pEList->nExpr); -#ifndef SQL_OMIT_CTE if (p->selFlags & SF_Recursive) { generateWithRecursiveQuery(pParse, p, &dest); } else -#endif /* Compound SELECTs that have an ORDER BY clause are handled separately. */ @@ -2982,7 +2968,6 @@ multiSelect(Parse * pParse, /* Parsing context */ sql_select_delete(db, pDelete); return rc; } -#endif /* SQL_OMIT_COMPOUND_SELECT */ /** * Code an output subroutine for a coroutine implementation of a @@ -3238,7 +3223,6 @@ generateOutputSubroutine(struct Parse *parse, struct Select *p, * until all data is exhausted then jump to the "end" labe. AltB, AeqB, * and AgtB jump to either L2 or to one of EofA or EofB. */ -#ifndef SQL_OMIT_COMPOUND_SELECT static int multiSelectOrderBy(Parse * pParse, /* Parsing context */ Select * p, /* The right-most of SELECTs to be coded */ @@ -3574,7 +3558,6 @@ multiSelectOrderBy(Parse * pParse, /* Parsing context */ explainComposite(pParse, p->op, iSub1, iSub2, 0); return pParse->is_aborted; } -#endif /* Forward Declarations */ static void substExprList(Parse *, ExprList *, int, ExprList *); @@ -4529,7 +4512,6 @@ convertCompoundSelectToSubquery(Walker * pWalker, Select * p) return WRC_Continue; } -#ifndef SQL_OMIT_CTE /* * Argument pWith (which may be NULL) points to a linked list of nested * WITH contexts, from inner to outermost. If the table identified by @@ -4717,9 +4699,7 @@ withExpand(Walker * pWalker, struct SrcList_item *pFrom) return SQL_OK; } -#endif -#ifndef SQL_OMIT_CTE /* * If the SELECT passed as the second argument has an associated WITH * clause, pop it from the stack stored as part of the Parse object. @@ -4738,9 +4718,6 @@ selectPopWith(Walker * pWalker, Select * p) pParse->pWith = pWith->pOuter; } } -#else -#define selectPopWith 0 -#endif /* * This routine is a Walker callback for "expanding" a SELECT statement. @@ -4805,12 +4782,12 @@ selectExpander(Walker * pWalker, Select * p) if (pFrom->fg.isRecursive) continue; assert(pFrom->space == NULL); -#ifndef SQL_OMIT_CTE + if (withExpand(pWalker, pFrom)) return WRC_Abort; if (pFrom->space != NULL) { } else -#endif + if (pFrom->zName == 0) { Select *pSel = pFrom->pSelect; /* A sub-query in the FROM clause of a SELECT */ @@ -5576,7 +5553,6 @@ sqlSelect(Parse * pParse, /* The parser context */ if (v == 0) goto select_end; -#ifndef SQL_OMIT_COMPOUND_SELECT /* Handle compound SELECT statements using the separate multiSelect() * procedure. */ @@ -5597,7 +5573,6 @@ sqlSelect(Parse * pParse, /* The parser context */ #endif return rc; } -#endif /* Generate code for all sub-queries in the FROM clause */ diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index a30582783d8f4eca2bb243dbb2216520d57b80a7..eb2d4cbb8d9e1024e9c9be34276642e81b88b40e 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -168,14 +168,6 @@ #define SQL_NOINLINE #endif -/* - * Powersafe overwrite is on by default. But can be turned off using - * the -Dsql_POWERSAFE_OVERWRITE=0 command-line option. - */ -#ifndef SQL_POWERSAFE_OVERWRITE -#define SQL_POWERSAFE_OVERWRITE 1 -#endif - /* * EVIDENCE-OF: R-25715-37072 Memory allocation statistics are enabled by * default unless sql is compiled with sql_DEFAULT_MEMSTATUS=0 in @@ -228,19 +220,14 @@ * can insure that all cases are evaluated. * */ -#ifdef SQL_COVERAGE_TEST -void sqlCoverage(int); -#define testcase(X) if( X ){ sqlCoverage(__LINE__); } -#else #define testcase(X) -#endif /* * The TESTONLY macro is used to enclose variable declarations or * other bits of code that are needed to support the arguments * within testcase() and assert() macros. */ -#if !defined(NDEBUG) || defined(SQL_COVERAGE_TEST) +#if !defined(NDEBUG) #define TESTONLY(X) X #else #define TESTONLY(X) @@ -270,15 +257,8 @@ void sqlCoverage(int); * hint of unplanned behavior. * * In other words, ALWAYS and NEVER are added for defensive code. - * - * When doing coverage testing ALWAYS and NEVER are hard-coded to - * be true and false so that the unreachable code they specify will - * not be counted as untested code. */ -#if defined(SQL_COVERAGE_TEST) || defined(SQL_MUTATION_TEST) -#define ALWAYS(X) (1) -#define NEVER(X) (0) -#elif !defined(NDEBUG) +#if !defined(NDEBUG) #define ALWAYS(X) ((X)?1:(assert(0),0)) #define NEVER(X) ((X)?(assert(0),1):0) #else @@ -286,12 +266,6 @@ void sqlCoverage(int); #define NEVER(X) (X) #endif -/* - * Return true (non-zero) if the input is an integer that is too large - * to fit in 32-bits. This macro is used inside of various testcase() - * macros to verify that we have tested sql for large-file support. - */ -#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) #include "hash.h" #include "parse.h" @@ -353,7 +327,6 @@ struct sql_vfs { #define SQL_LIMIT_ATTACHED 7 #define SQL_LIMIT_LIKE_PATTERN_LENGTH 8 #define SQL_LIMIT_TRIGGER_DEPTH 9 -#define SQL_LIMIT_WORKER_THREADS 10 enum sql_ret_code { /** Result of a routine is ok. */ @@ -410,18 +383,12 @@ sql_malloc(int); void * sql_malloc64(sql_uint64); -void * -sql_realloc(void *, int); - void * sql_realloc64(void *, sql_uint64); void sql_free(void *); -sql_uint64 -sql_msize(void *); - int sql_stricmp(const char *, const char *); @@ -626,36 +593,20 @@ sql_exec(sql *, /* An open database */ #define SQL_IOERR_READ (SQL_IOERR | (1<<8)) #define SQL_IOERR_SHORT_READ (SQL_IOERR | (2<<8)) #define SQL_IOERR_WRITE (SQL_IOERR | (3<<8)) -#define SQL_IOERR_FSYNC (SQL_IOERR | (4<<8)) #define SQL_IOERR_DIR_FSYNC (SQL_IOERR | (5<<8)) #define SQL_IOERR_TRUNCATE (SQL_IOERR | (6<<8)) #define SQL_IOERR_FSTAT (SQL_IOERR | (7<<8)) #define SQL_IOERR_UNLOCK (SQL_IOERR | (8<<8)) #define SQL_IOERR_RDLOCK (SQL_IOERR | (9<<8)) #define SQL_IOERR_DELETE (SQL_IOERR | (10<<8)) -#define SQL_IOERR_BLOCKED (SQL_IOERR | (11<<8)) #define SQL_IOERR_NOMEM (SQL_IOERR | (12<<8)) #define SQL_IOERR_ACCESS (SQL_IOERR | (13<<8)) -#define SQL_IOERR_CHECKRESERVEDLOCK (SQL_IOERR | (14<<8)) -#define SQL_IOERR_LOCK (SQL_IOERR | (15<<8)) #define SQL_IOERR_CLOSE (SQL_IOERR | (16<<8)) -#define SQL_IOERR_DIR_CLOSE (SQL_IOERR | (17<<8)) -#define SQL_IOERR_SHMOPEN (SQL_IOERR | (18<<8)) -#define SQL_IOERR_SHMSIZE (SQL_IOERR | (19<<8)) -#define SQL_IOERR_SHMLOCK (SQL_IOERR | (20<<8)) -#define SQL_IOERR_SHMMAP (SQL_IOERR | (21<<8)) -#define SQL_IOERR_SEEK (SQL_IOERR | (22<<8)) #define SQL_IOERR_DELETE_NOENT (SQL_IOERR | (23<<8)) -#define SQL_IOERR_MMAP (SQL_IOERR | (24<<8)) #define SQL_IOERR_GETTEMPPATH (SQL_IOERR | (25<<8)) -#define SQL_IOERR_CONVPATH (SQL_IOERR | (26<<8)) -#define SQL_IOERR_VNODE (SQL_IOERR | (27<<8)) #define SQL_CONSTRAINT_FOREIGNKEY (SQL_CONSTRAINT | (3<<8)) -#define SQL_CONSTRAINT_FUNCTION (SQL_CONSTRAINT | (4<<8)) #define SQL_CONSTRAINT_NOTNULL (SQL_CONSTRAINT | (5<<8)) -#define SQL_CONSTRAINT_PRIMARYKEY (SQL_CONSTRAINT | (6<<8)) #define SQL_CONSTRAINT_TRIGGER (SQL_CONSTRAINT | (7<<8)) -#define SQL_CONSTRAINT_UNIQUE (SQL_CONSTRAINT | (8<<8)) /** * Subtype of a main type. Allows to do some subtype specific @@ -702,22 +653,6 @@ sql_initialize(void); int sql_os_end(void); -#define SQL_CONFIG_SCRATCH 6 /* void*, int sz, int N */ -#define SQL_CONFIG_MEMSTATUS 9 /* boolean */ -#define SQL_CONFIG_LOOKASIDE 13 /* int int */ -#define SQL_CONFIG_LOG 16 /* xFunc, void* */ -#define SQL_CONFIG_URI 17 /* int */ -#define SQL_CONFIG_COVERING_INDEX_SCAN 20 /* int */ -#define SQL_CONFIG_SQLLOG 21 /* xSqllog, void* */ -#define SQL_CONFIG_MMAP_SIZE 22 /* sql_int64, sql_int64 */ -#define SQL_CONFIG_PMASZ 24 /* unsigned int szPma */ -#define SQL_CONFIG_STMTJRNL_SPILL 25 /* int nByte */ - -#define SQL_DBCONFIG_LOOKASIDE 1001 /* void* int int */ -#define SQL_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ -#define SQL_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ -#define SQL_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ - #define SQL_TRACE_STMT 0x01 #define SQL_TRACE_PROFILE 0x02 #define SQL_TRACE_ROW 0x04 @@ -726,10 +661,6 @@ sql_os_end(void); #define SQL_DETERMINISTIC 0x800 #define SQL_STATUS_MEMORY_USED 0 -#define SQL_STATUS_PAGECACHE_USED 1 -#define SQL_STATUS_PAGECACHE_OVERFLOW 2 -#define SQL_STATUS_SCRATCH_USED 3 -#define SQL_STATUS_SCRATCH_OVERFLOW 4 #define SQL_STATUS_MALLOC_SIZE 5 #define SQL_STATUS_PARSER_STACK 6 #define SQL_STATUS_PAGECACHE_SIZE 7 @@ -762,41 +693,12 @@ sql_create_function_v2(sql * db, #define SQL_OPEN_CREATE 0x00000004 /* Ok for sql_open_v2() */ #define SQL_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQL_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ -#define SQL_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQL_OPEN_URI 0x00000040 /* Ok for sql_open_v2() */ -#define SQL_OPEN_MEMORY 0x00000080 /* Ok for sql_open_v2() */ #define SQL_OPEN_MAIN_DB 0x00000100 /* VFS only */ -#define SQL_OPEN_TEMP_DB 0x00000200 /* VFS only */ -#define SQL_OPEN_SHAREDCACHE 0x00020000 /* Ok for sql_open_v2() */ -#define SQL_OPEN_PRIVATECACHE 0x00040000 /* Ok for sql_open_v2() */ sql_vfs * sql_vfs_find(const char *zVfsName); -#define SQL_TESTCTRL_FIRST 5 -#define SQL_TESTCTRL_PRNG_SAVE 5 -#define SQL_TESTCTRL_PRNG_RESTORE 6 -#define SQL_TESTCTRL_PRNG_RESET 7 -#define SQL_TESTCTRL_BITVEC_TEST 8 -#define SQL_TESTCTRL_FAULT_INSTALL 9 -#define SQL_TESTCTRL_BENIGN_MALLOC_HOOKS 10 -#define SQL_TESTCTRL_PENDING_BYTE 11 -#define SQL_TESTCTRL_ASSERT 12 -#define SQL_TESTCTRL_ALWAYS 13 -#define SQL_TESTCTRL_RESERVE 14 -#define SQL_TESTCTRL_OPTIMIZATIONS 15 -#define SQL_TESTCTRL_ISKEYWORD 16 -#define SQL_TESTCTRL_SCRATCHMALLOC 17 -#define SQL_TESTCTRL_LOCALTIME_FAULT 18 -#define SQL_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ -#define SQL_TESTCTRL_ONCE_RESET_THRESHOLD 19 -#define SQL_TESTCTRL_NEVER_CORRUPT 20 -#define SQL_TESTCTRL_VDBE_COVERAGE 21 -#define SQL_TESTCTRL_BYTEORDER 22 -#define SQL_TESTCTRL_ISINIT 23 -#define SQL_TESTCTRL_SORTER_MMAP 24 -#define SQL_TESTCTRL_LAST 24 - int sql_status64(int op, sql_int64 * pCurrent, sql_int64 * pHighwater, @@ -821,22 +723,13 @@ struct sql_io_methods { }; #define SQL_FCNTL_LOCKSTATE 1 -#define SQL_FCNTL_GET_LOCKPROXYFILE 2 -#define SQL_FCNTL_SET_LOCKPROXYFILE 3 #define SQL_FCNTL_LAST_ERRNO 4 #define SQL_FCNTL_SIZE_HINT 5 #define SQL_FCNTL_CHUNK_SIZE 6 -#define SQL_FCNTL_FILE_POINTER 7 -#define SQL_FCNTL_SYNC_OMITTED 8 -#define SQL_FCNTL_OVERWRITE 10 #define SQL_FCNTL_VFSNAME 11 -#define SQL_FCNTL_POWERSAFE_OVERWRITE 12 -#define SQL_FCNTL_PRAGMA 13 #define SQL_FCNTL_TEMPFILENAME 15 #define SQL_FCNTL_MMAP_SIZE 16 -#define SQL_FCNTL_TRACE 17 #define SQL_FCNTL_HAS_MOVED 18 -#define SQL_FCNTL_SYNC 19 int sql_os_init(void); @@ -847,10 +740,6 @@ sql_soft_heap_limit64(sql_int64 N); int sql_limit(sql *, int id, int newVal); -#define SQL_SYNC_NORMAL 0x00002 -#define SQL_SYNC_FULL 0x00003 -#define SQL_SYNC_DATAONLY 0x00010 - extern char * sql_temp_directory; @@ -858,10 +747,6 @@ const char * sql_uri_parameter(const char *zFilename, const char *zParam); -#define SQL_ACCESS_EXISTS 0 -#define SQL_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ -#define SQL_ACCESS_READ 2 /* Unused */ - #define SQL_DBSTATUS_LOOKASIDE_USED 0 #define SQL_DBSTATUS_CACHE_USED 1 #define SQL_DBSTATUS_SCHEMA_USED 2 @@ -995,35 +880,6 @@ sql_bind_parameter_lindex(sql_stmt * pStmt, const char *zName, #define SQL_DEFAULT_RECURSIVE_TRIGGERS 0 #endif -/* - * Provide a default value for sql_TEMP_STORE in case it is not specified - * on the command-line - */ -#ifndef SQL_TEMP_STORE -#define SQL_TEMP_STORE 1 -#define SQL_TEMP_STORE_xc 1 /* Exclude from ctime.c */ -#endif - -/* - * If no value has been provided for sql_MAX_WORKER_THREADS, or if - * sql_TEMP_STORE is set to 3 (never use temporary files), set it - * to zero. - */ -#if SQL_TEMP_STORE==3 -#undef SQL_MAX_WORKER_THREADS -#define SQL_MAX_WORKER_THREADS 0 -#endif -#ifndef SQL_MAX_WORKER_THREADS -#define SQL_MAX_WORKER_THREADS 8 -#endif -#ifndef SQL_DEFAULT_WORKER_THREADS -#define SQL_DEFAULT_WORKER_THREADS 0 -#endif -#if SQL_DEFAULT_WORKER_THREADS>SQL_MAX_WORKER_THREADS -#undef SQL_MAX_WORKER_THREADS -#define SQL_MAX_WORKER_THREADS SQL_DEFAULT_WORKER_THREADS -#endif - /** * Default count of allowed compound selects. * @@ -1195,41 +1051,6 @@ typedef u64 uptr; */ #define SQL_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) -/* - * Macros to determine whether the machine is big or little endian, - * and whether or not that determination is run-time or compile-time. - * - * For best performance, an attempt is made to guess at the byte-order - * using C-preprocessor macros. If that is unsuccessful, or if - * -Dsql_RUNTIME_BYTEORDER=1 is set, then byte-order is determined - * at run-time. - */ -#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ - defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ - defined(__arm__)) && !defined(SQL_RUNTIME_BYTEORDER) -#define SQL_BYTEORDER 1234 -#define SQL_BIGENDIAN 0 -#define SQL_LITTLEENDIAN 1 -#endif -#if (defined(sparc) || defined(__ppc__)) \ - && !defined(SQL_RUNTIME_BYTEORDER) -#define SQL_BYTEORDER 4321 -#define SQL_BIGENDIAN 1 -#define SQL_LITTLEENDIAN 0 -#endif -#if !defined(SQL_BYTEORDER) -#ifdef SQL_AMALGAMATION -const int sqlone = 1; -#else -extern const int sqlone; -#endif -#define SQL_BYTEORDER 0 /* 0 means "unknown at compile-time" */ -#define SQL_BIGENDIAN (*(char *)(&sqlone)==0) -#define SQL_LITTLEENDIAN (*(char *)(&sqlone)==1) -#define SQL_UTF16NATIVE (SQL_BIGENDIAN?SQL_UTF16BE:SQL_UTF16LE) -#endif - /* * Constants for the largest and smallest possible 64-bit signed integers. * These macros are designed to work correctly on both 32-bit and 64-bit @@ -1399,7 +1220,7 @@ typedef int VList; * The number of different kinds of things that can be limited * using the sql_limit() interface. */ -#define SQL_N_LIMIT (SQL_LIMIT_WORKER_THREADS+1) +#define SQL_N_LIMIT (SQL_LIMIT_TRIGGER_DEPTH+1) /* * Lookaside malloc is a set of fixed-size buffers that can be used @@ -1461,7 +1282,6 @@ struct sql { int iSysErrno; /* Errno value from last system error */ u16 dbOptFlags; /* Flags to enable/disable optimizations */ u8 enc; /* Text encoding */ - u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ u8 bBenignMalloc; /* Do not require OOMs if true */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ @@ -1497,11 +1317,9 @@ struct sql { double notUsed1; /* Spacer */ } u1; Lookaside lookaside; /* Lookaside malloc configuration */ -#ifndef SQL_OMIT_PROGRESS_CALLBACK int (*xProgress) (void *); /* The progress callback */ void *pProgressArg; /* Argument to the progress callback */ unsigned nProgressOps; /* Number of opcodes for progress callback */ -#endif Hash aFunc; /* Hash table of connection functions */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ }; @@ -2943,9 +2761,7 @@ struct sqlConfig { void (*xVdbeBranch) (void *, int iSrcLine, u8 eThis, u8 eMx); /* Callback */ void *pVdbeBranchArg; /* 1st argument */ #endif -#ifndef SQL_UNTESTABLE int (*xTestCallback) (int); /* Invoked by sqlFaultSim() */ -#endif int bLocaltimeFault; /* True to fail localtime() calls */ int iOnceResetThreshold; /* When to reset OP_Once counters */ }; @@ -3014,16 +2830,6 @@ struct TreeView { }; #endif /* SQL_DEBUG */ -/* - * Assuming zIn points to the first byte of a UTF-8 character, - * advance zIn to point to the first byte of the next UTF-8 character. - */ -#define SQL_SKIP_UTF8(zIn) { \ - if( (*(zIn++))>=0xc0 ){ \ - while( (*zIn & 0xc0)==0x80 ){ zIn++; } \ - } \ -} - /* * The following macros mimic the standard library functions toupper(), * isspace(), isalnum(), isdigit() and isxdigit(), respectively. The @@ -3046,7 +2852,6 @@ unsigned sqlStrlen30(const char *); #define sqlStrNICmp sql_strnicmp void sqlMallocInit(void); -void sqlMallocEnd(void); void *sqlMalloc(u64); void *sqlMallocZero(u64); void *sqlDbMallocZero(sql *, u64); @@ -3060,14 +2865,7 @@ void *sqlDbRealloc(sql *, void *, u64); void sqlDbFree(sql *, void *); int sqlMallocSize(void *); int sqlDbMallocSize(sql *, void *); -void *sqlScratchMalloc(int); -void sqlScratchFree(void *); -void *sqlPageMalloc(int); -void sqlPageFree(void *); -void sqlMemSetDefault(void); -#ifndef SQL_UNTESTABLE void sqlBenignMallocHooks(void (*)(void), void (*)(void)); -#endif int sqlHeapNearlyFull(void); /* @@ -3124,7 +2922,6 @@ void sqlTreeViewSelect(TreeView *, const Select *, u8); void sqlTreeViewWith(TreeView *, const With *); #endif -void sqlSetString(char **, sql *, const char *); void sqlDequote(char *); /** @@ -3195,9 +2992,6 @@ void sqlReleaseTempReg(Parse *, int); int sqlGetTempRange(Parse *, int); void sqlReleaseTempRange(Parse *, int, int); void sqlClearTempRegCache(Parse *); -#ifdef SQL_DEBUG -int sqlNoTempsInRange(Parse *, int, int); -#endif /** * Construct a new expression. Memory for this node and for the @@ -3404,11 +3198,7 @@ int vdbe_emit_open_cursor(struct Parse *parse, int cursor, int index_id, struct space *space); -#ifdef SQL_UNTESTABLE -#define sqlFaultSim(X) SQL_OK -#else int sqlFaultSim(int); -#endif /** * The parser calls this routine in order to create a new VIEW. @@ -3665,7 +3455,6 @@ void sqlExprCacheRemove(Parse *, int, int); void sqlExprCacheClear(Parse *); void sql_expr_type_cache_change(Parse *, int, int); void sqlExprCode(Parse *, Expr *, int); -void sqlExprCodeCopy(Parse *, Expr *, int); void sqlExprCodeFactorable(Parse *, Expr *, int); void sqlExprCodeAtInit(Parse *, Expr *, int, u8); int sqlExprCodeTemp(Parse *, Expr *, int *); @@ -3710,10 +3499,6 @@ void sqlExprAnalyzeAggregates(NameContext *, Expr *); void sqlExprAnalyzeAggList(NameContext *, ExprList *); int sqlFunctionUsesThisSrc(Expr *, SrcList *); Vdbe *sqlGetVdbe(Parse *); -#ifndef SQL_UNTESTABLE -void sqlPrngSaveState(void); -void sqlPrngRestoreState(void); -#endif void sqlRollbackAll(Vdbe *); /** @@ -4533,7 +4318,6 @@ void sqlVdbeSetChanges(sql *, int); int sqlAddInt64(i64 *, i64); int sqlSubInt64(i64 *, i64); int sqlMulInt64(i64 *, i64); -int sqlAbsInt32(int); u8 sqlGetBoolean(const char *z, u8); const void *sqlValueText(sql_value *); @@ -4546,16 +4330,14 @@ sql_value *sqlValueNew(sql *); int sqlValueFromExpr(sql *, Expr *, enum field_type type, sql_value **); void sql_value_apply_type(sql_value *val, enum field_type type); -#ifndef SQL_AMALGAMATION + extern const unsigned char sqlOpcodeProperty[]; -extern const char sqlStrBINARY[]; extern const unsigned char sqlUpperToLower[]; extern const unsigned char sqlCtypeMap[]; extern const Token sqlIntTokens[]; extern SQL_WSD struct sqlConfig sqlConfig; extern FuncDefHash sqlBuiltinFunctions; extern int sqlPendingByte; -#endif /** * Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" @@ -4860,15 +4642,9 @@ collations_check_compatibility(uint32_t lhs_id, bool is_lhs_forced, int sql_binary_compare_coll_seq(Parse *parser, Expr *left, Expr *right, uint32_t *id); -int sqlTempInMemory(const sql *); -#ifndef SQL_OMIT_CTE With *sqlWithAdd(Parse *, With *, Token *, ExprList *, Select *); void sqlWithDelete(sql *, With *); void sqlWithPush(Parse *, With *, u8); -#else -#define sqlWithPush(x,y,z) -#define sqlWithDelete(x,y) -#endif /* * This function is called when inserting, deleting or updating a @@ -4932,24 +4708,12 @@ fk_constraint_emit_actions(struct Parse *parser, struct space *space, int reg_ol bool fk_constraint_is_required(struct space *space, const int *changes); -/* - * Available fault injectors. Should be numbered beginning with 0. - */ -#define SQL_FAULTINJECTOR_MALLOC 0 -#define SQL_FAULTINJECTOR_COUNT 1 - /* * The interface to the code in fault.c used for identifying "benign" - * malloc failures. This is only present if sql_UNTESTABLE - * is not defined. + * malloc failures. */ -#ifndef SQL_UNTESTABLE void sqlBeginBenignMalloc(void); void sqlEndBenignMalloc(void); -#else -#define sqlBeginBenignMalloc() -#define sqlEndBenignMalloc() -#endif /* * Allowed return values from sqlFindInIndex() @@ -4975,28 +4739,10 @@ int sqlExprCheckHeight(Parse *, int); #define sqlExprCheckHeight(x,y) #endif -u32 sqlGet4byte(const u8 *); -void sqlPut4byte(u8 *, u32); - #ifdef SQL_DEBUG void sqlParserTrace(FILE *, char *); #endif -/* - * If the sql_ENABLE IOTRACE exists then the global variable - * sqlIoTrace is a pointer to a printf-like routine used to - * print I/O tracing messages. - */ -#ifdef SQL_ENABLE_IOTRACE -#define IOTRACE(A) if( sqlIoTrace ){ sqlIoTrace A; } -void sqlVdbeIOTraceSql(Vdbe *); - SQL_EXTERN void (SQL_CDECL * sqlIoTrace) (const char *, - ...); -#else -#define IOTRACE(A) -#define sqlVdbeIOTraceSql(X) -#endif - /* * These routines are available for the mem2.c debugging memory allocator * only. They are used to verify that different "types" of memory @@ -5036,16 +4782,7 @@ int sqlMemdebugNoType(void *, u8); #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ -#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ -#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ -/* - * Threading interface - */ -#if SQL_MAX_WORKER_THREADS>0 -int sqlThreadCreate(sqlThread **, void *(*)(void *), void *); -int sqlThreadJoin(sqlThread *, void **); -#endif int sqlExprVectorSize(Expr * pExpr); int sqlExprIsVector(Expr * pExpr); diff --git a/src/box/sql/treeview.c b/src/box/sql/treeview.c index 5acea582acbc0416780c18da3c5a4d1e0da99d33..a04597979bb0149bb9c350fa1e6316491061c7ad 100644 --- a/src/box/sql/treeview.c +++ b/src/box/sql/treeview.c @@ -382,14 +382,14 @@ sqlTreeViewExpr(TreeView * pView, const Expr * pExpr, u8 moreToFollow) pExpr->u.zToken); break; } -#ifndef SQL_OMIT_CAST + case TK_CAST:{ /* Expressions of the form: CAST(pLeft AS token) */ sqlTreeViewLine(pView, "CAST %Q", pExpr->u.zToken); sqlTreeViewExpr(pView, pExpr->pLeft, 0); break; } -#endif /* SQL_OMIT_CAST */ + case TK_LT: zBinOp = "LT"; break; diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c index bf5c2e00b63ad1d28f2a7f447199529eae919df7..d1aafac5a7a19bea10d60947fce1556100f0623b 100644 --- a/src/box/sql/trigger.c +++ b/src/box/sql/trigger.c @@ -770,12 +770,10 @@ sql_row_trigger_program(struct Parse *parser, struct sql_trigger *trigger, (trigger->op == TK_INSERT ? "INSERT" : ""), (trigger->op == TK_DELETE ? "DELETE" : ""), space->def->name)); -#ifndef SQL_OMIT_TRACE sqlVdbeChangeP4(v, -1, sqlMPrintf(db, "-- TRIGGER %s", trigger->zName), P4_DYNAMIC); -#endif /* * If one was specified, code the WHEN clause. If diff --git a/src/box/sql/util.c b/src/box/sql/util.c index d5c93f8aa37183825a64e01ced7014c51d3ba362..39632e38d1bc6db58ce53bf9422963a6c8e8ab54 100644 --- a/src/box/sql/util.c +++ b/src/box/sql/util.c @@ -38,25 +38,11 @@ */ #include "sqlInt.h" #include <stdarg.h> -#if HAVE_ISNAN || SQL_HAVE_ISNAN #include <math.h> -#endif #include "coll/coll.h" #include <unicode/ucasemap.h> #include "errinj.h" -/* - * Routine needed to support the testcase() macro. - */ -#ifdef SQL_COVERAGE_TEST -void -sqlCoverage(int x) -{ - static unsigned dummy = 0; - dummy += (unsigned)x; -} -#endif - /* * Give a callback to the test harness that can be used to simulate faults * in places where it is difficult or expensive to do so purely by means @@ -68,14 +54,12 @@ sqlCoverage(int x) * Return whatever integer value the test callback returns, or return * SQL_OK if no test callback is installed. */ -#ifndef SQL_UNTESTABLE int sqlFaultSim(int iTest) { int (*xCallback) (int) = sqlGlobalConfig.xTestCallback; return xCallback ? xCallback(iTest) : SQL_OK; } -#endif /* * Return true if the floating point value is Not a Number (NaN). @@ -87,30 +71,7 @@ int sqlIsNaN(double x) { int rc; /* The value return */ -#if !SQL_HAVE_ISNAN && !HAVE_ISNAN - /* - * Systems that support the isnan() library function should probably - * make use - * - * This NaN test sometimes fails if compiled on GCC with -ffast-math. - * On the other hand, the use of -ffast-math comes with the following - * warning: - * - * This option [-ffast-math] should never be turned on by any - * -O option since it can result in incorrect output for programs - * which depend on an exact implementation of IEEE or ISO - * rules/specifications for math functions. - */ -#ifdef __FAST_MATH__ -#error sql will not work correctly with the -ffast-math option of GCC. -#endif - volatile double y = x; - volatile double z = y; - rc = (y != z); -#else /* if HAVE_ISNAN */ rc = isnan(x); -#endif /* HAVE_ISNAN */ - testcase(rc); return rc; } @@ -1123,53 +1084,6 @@ sqlVarintLen(u64 v) return i; } -/* - * Read or write a four-byte big-endian integer value. - */ -u32 -sqlGet4byte(const u8 * p) -{ -#if SQL_BYTEORDER==4321 - u32 x; - memcpy(&x, p, 4); - return x; -#elif SQL_BYTEORDER==1234 && !defined(SQL_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=4003000 - u32 x; - memcpy(&x, p, 4); - return __builtin_bswap32(x); -#elif SQL_BYTEORDER==1234 && !defined(SQL_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 - u32 x; - memcpy(&x, p, 4); - return _byteswap_ulong(x); -#else - testcase(p[0] & 0x80); - return ((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; -#endif -} - -void -sqlPut4byte(unsigned char *p, u32 v) -{ -#if SQL_BYTEORDER==4321 - memcpy(p, &v, 4); -#elif SQL_BYTEORDER==1234 && !defined(SQL_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=4003000 - u32 x = __builtin_bswap32(v); - memcpy(p, &x, 4); -#elif SQL_BYTEORDER==1234 && !defined(SQL_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 - u32 x = _byteswap_ulong(v); - memcpy(p, &x, 4); -#else - p[0] = (u8) (v >> 24); - p[1] = (u8) (v >> 16); - p[2] = (u8) (v >> 8); - p[3] = (u8) v; -#endif -} - /* * Translate a single byte of Hex into an integer. * This routine only works if h really is a valid hexadecimal @@ -1343,20 +1257,6 @@ sqlMulInt64(i64 * pA, i64 iB) return 0; } -/* - * Compute the absolute value of a 32-bit signed integer, of possible. Or - * if the integer has a value of -2147483648, return +2147483647 - */ -int -sqlAbsInt32(int x) -{ - if (x >= 0) - return x; - if (x == (int)0x80000000) - return 0x7fffffff; - return -x; -} - /* * Find (an approximate) sum of two LogEst values. This computation is * not a simple "+" operator because LogEst is stored as a logarithmic @@ -1437,16 +1337,10 @@ sqlLogEstToInt(LogEst x) n -= 2; else if (n >= 1) n -= 1; -#if defined(SQL_ENABLE_STMT_SCANSTATUS) || \ - defined(SQL_EXPLAIN_ESTIMATED_ROWS) - if (x > 60) - return (u64) LARGEST_INT64; -#else /* The largest input possible to this routine is 310, * resulting in a maximum x of 31 */ assert(x <= 60); -#endif return x >= 3 ? (n + 8) << (x - 3) : (n + 8) >> (3 - x); } diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 3f0b856b3cba2d3186ab0e02820b7055f431f141..79a4175bec14f1cb964f7398ddf4ccb6df9188bf 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -147,7 +147,7 @@ int sql_found_count = 0; * Test a register to see if it exceeds the current maximum blob size. * If it does, record the new maximum blob size. */ -#if defined(SQL_TEST) && !defined(SQL_UNTESTABLE) +#if defined(SQL_TEST) # define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) #else # define UPDATE_MAX_BLOBSIZE(P) @@ -746,9 +746,7 @@ int sqlVdbeExec(Vdbe *p) sql *db = p->db; /* The database */ int iCompare = 0; /* Result of last comparison */ unsigned nVmStep = 0; /* Number of virtual machine steps */ -#ifndef SQL_OMIT_PROGRESS_CALLBACK unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */ -#endif Mem *aMem = p->aMem; /* Copy of p->aMem */ Mem *pIn1 = 0; /* 1st input operand */ Mem *pIn2 = 0; /* 2nd input operand */ @@ -773,14 +771,13 @@ int sqlVdbeExec(Vdbe *p) assert(p->explain==0); p->pResultSet = 0; if (db->u1.isInterrupted) goto abort_due_to_interrupt; - sqlVdbeIOTraceSql(p); -#ifndef SQL_OMIT_PROGRESS_CALLBACK + if (db->xProgress) { u32 iPrior = p->aCounter[SQL_STMTSTATUS_VM_STEP]; assert(0 < db->nProgressOps); nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps); } -#endif + #ifdef SQL_DEBUG sqlBeginBenignMalloc(); if (p->pc == 0 && @@ -819,9 +816,6 @@ int sqlVdbeExec(Vdbe *p) start = sqlHwtime(); #endif nVmStep++; -#ifdef SQL_ENABLE_STMT_SCANSTATUS - if (p->anExec) p->anExec[(int)(pOp-aOp)]++; -#endif /* Only allow tracing if SQL_DEBUG is defined. */ @@ -938,7 +932,7 @@ case OP_Goto: { /* jump */ */ check_for_interrupt: if (db->u1.isInterrupted) goto abort_due_to_interrupt; -#ifndef SQL_OMIT_PROGRESS_CALLBACK + /* Call the progress callback if it is configured and the required number * of VDBE ops have been executed (either since this invocation of * sqlVdbeExec() or since last time the progress callback was called). @@ -953,7 +947,6 @@ case OP_Goto: { /* jump */ goto abort_due_to_error; } } -#endif break; } @@ -1517,7 +1510,6 @@ case OP_ResultRow: { assert(pOp->p1>0); assert(pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1); -#ifndef SQL_OMIT_PROGRESS_CALLBACK /* Run the progress counter just before returning. */ if (db->xProgress!=0 @@ -1527,7 +1519,6 @@ case OP_ResultRow: { rc = SQL_INTERRUPT; goto abort_due_to_error; } -#endif /* If this statement has violated immediate foreign key constraints, do * not return the number of rows modified. And do not RELEASE the statement @@ -2088,7 +2079,6 @@ case OP_Realify: { /* in1 */ break; } -#ifndef SQL_OMIT_CAST /* Opcode: Cast P1 P2 * * * * Synopsis: type(r[P1]) * @@ -2118,7 +2108,6 @@ case OP_Cast: { /* in1 */ rc = SQL_TARANTOOL_ERROR; goto abort_due_to_error; } -#endif /* SQL_OMIT_CAST */ /* Opcode: Eq P1 P2 P3 P4 P5 * Synopsis: IF r[P3]==r[P1] @@ -3373,26 +3362,6 @@ case OP_Close: { break; } -#ifdef SQL_ENABLE_COLUMN_USED_MASK -/* Opcode: ColumnsUsed P1 * * P4 * - * - * This opcode (which only exists if sql was compiled with - * SQL_ENABLE_COLUMN_USED_MASK) identifies which columns of the - * table or index for cursor P1 are used. P4 is a 64-bit integer - * (P4_INT64) in which the first 63 bits are one for each of the - * first 63 columns of the table or index that are actually used - * by the cursor. The high-order bit is set if any column after - * the 64th is used. - */ -case OP_ColumnsUsed: { - VdbeCursor *pC; - pC = p->apCsr[pOp->p1]; - assert(pC->eCurType==CURTYPE_TARANTOOL); - pC->maskUsed = *(u64*)pOp->p4.pI64; - break; -} -#endif - /* Opcode: SeekGE P1 P2 P3 P4 P5 * Synopsis: key=r[P3@P4] * @@ -4979,9 +4948,6 @@ case OP_Program: { /* jump */ pFrame->aOp = p->aOp; pFrame->nOp = p->nOp; pFrame->token = pProgram->token; -#ifdef SQL_ENABLE_STMT_SCANSTATUS - pFrame->anExec = p->anExec; -#endif pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++) { @@ -5011,9 +4977,6 @@ case OP_Program: { /* jump */ p->apCsr = (VdbeCursor **)&aMem[p->nMem]; p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; -#ifdef SQL_ENABLE_STMT_SCANSTATUS - p->anExec = 0; -#endif pOp = &aOp[-1]; break; @@ -5379,7 +5342,6 @@ case OP_Init: { /* jump */ break; } -#ifndef SQL_OMIT_TRACE if ((db->mTrace & SQL_TRACE_STMT)!=0 && !p->doingRerun && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 @@ -5393,7 +5355,6 @@ case OP_Init: { /* jump */ (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql)) != 0) sqlDebugPrintf("SQL-trace: %s\n", zTrace); #endif /* SQL_DEBUG */ -#endif /* SQL_OMIT_TRACE */ assert(pOp->p2>0); if (pOp->p1>=sqlGlobalConfig.iOnceResetThreshold) { for(i=1; i<p->nOp; i++) { diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h index 09ea8935b229dc7c0fc58895b824be2d21b8d0a5..a609e8cc84fec215466b5c4b82093f4e015d0f5c 100644 --- a/src/box/sql/vdbe.h +++ b/src/box/sql/vdbe.h @@ -151,11 +151,7 @@ struct SubProgram { #define COLNAME_DATABASE 2 #define COLNAME_TABLE 3 #define COLNAME_COLUMN 4 -#ifdef SQL_ENABLE_COLUMN_METADATA -#define COLNAME_N 5 /* Number of COLNAME_xxx symbols */ -#else -#define COLNAME_N 2 /* Store the name and decltype */ -#endif +#define COLNAME_N 2 /* Store the name and decltype */ /* * The following macro converts a relative address in the p2 field @@ -267,9 +263,7 @@ void sqlVdbeSwap(Vdbe *, Vdbe *); VdbeOp *sqlVdbeTakeOpArray(Vdbe *, int *, int *); sql_value *sqlVdbeGetBoundValue(Vdbe *, int, u8); void sqlVdbeSetVarmask(Vdbe *, int); -#ifndef SQL_OMIT_TRACE char *sqlVdbeExpandSql(Vdbe *, const char *); -#endif int sqlMemCompare(const Mem *, const Mem *, const struct coll *); /** @@ -350,11 +344,4 @@ void sqlVdbeSetLineNumber(Vdbe *, int); #define VdbeCoverageNeverTaken(v) #define VDBE_OFFSET_LINENO(x) 0 #endif - -#ifdef SQL_ENABLE_STMT_SCANSTATUS -void sqlVdbeScanStatus(Vdbe *, int, int, int, LogEst, const char *); -#else -#define sqlVdbeScanStatus(a,b,c,d,e) -#endif - #endif /* SQL_VDBE_H */ diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h index 68e867fbe0794856e110e1dca3671b4d70b1a1f5..9bfa51ecedcf8cb296ae0ddfcd28292c5669a194 100644 --- a/src/box/sql/vdbeInt.h +++ b/src/box/sql/vdbeInt.h @@ -112,9 +112,6 @@ struct VdbeCursor { /** Info about keys needed by index cursors. */ struct key_def *key_def; i16 nField; /* Number of fields in the header */ -#ifdef SQL_ENABLE_COLUMN_USED_MASK - u64 maskUsed; /* Mask of columns used by this cursor */ -#endif /** * Auxiliary VDBE structure to speed-up tuple data * field access. @@ -421,9 +418,7 @@ struct Vdbe { */ uint32_t res_var_count; VList *pVList; /* Name of variables */ -#ifndef SQL_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ -#endif int nOp; /* Number of instructions in the program */ u16 nResColumn; /* Number of columns in one row of the result set */ u8 errorAction; /* Recovery action to do in case of an error */ @@ -446,11 +441,6 @@ struct Vdbe { uint32_t sql_flags; /* Anonymous savepoint for aborts only */ Savepoint *anonymous_savepoint; -#ifdef SQL_ENABLE_STMT_SCANSTATUS - i64 *anExec; /* Number of times each op has been executed */ - int nScan; /* Entries in aScan[] */ - ScanStatus *aScan; /* Scan definitions for sql_stmt_scanstatus() */ -#endif }; /* diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c index ace1eceb12e08c7119a46327612bc725cfd75452..cd8d3527b6848c4192c92909a9800612f6e6ff25 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -66,7 +66,6 @@ vdbeSafetyNotNull(Vdbe * p) } } -#ifndef SQL_OMIT_TRACE /* * Invoke the profile callback. This routine is only called if we already * know that the profile callback is defined and needs to be invoked. @@ -98,9 +97,6 @@ invokeProfileCallback(sql * db, Vdbe * p) */ #define checkProfileCallback(DB,P) \ if( ((P)->startTime)>0 ){ invokeProfileCallback(DB,P); } -#else -#define checkProfileCallback(DB,P) /*no-op */ -#endif /* * The following routine destroys a virtual machine that is created by @@ -496,21 +492,9 @@ sqlStep(Vdbe * p) * * Nevertheless, some published applications that were originally written * for version 3.6.23 or earlier do in fact depend on SQL_MISUSE - * returns, and those were broken by the automatic-reset change. As a - * a work-around, the SQL_OMIT_AUTORESET compile-time restores the - * legacy behavior of returning SQL_MISUSE for cases where the - * previous sql_step() returned something other than a SQL_LOCKED - * or SQL_BUSY error. + * returns, and those were broken by the automatic-reset change. */ -#ifdef SQL_OMIT_AUTORESET - if ((rc = p->rc & 0xff) == SQL_BUSY || rc == SQL_LOCKED) { - sql_reset((sql_stmt *) p); - } else { - return SQL_MISUSE; - } -#else sql_reset((sql_stmt *) p); -#endif } /* Check that malloc() has not failed. If it has, return early. */ @@ -534,14 +518,12 @@ sqlStep(Vdbe * p) db->u1.isInterrupted = 0; } -#ifndef SQL_OMIT_TRACE if ((db->xProfile || (db->mTrace & SQL_TRACE_PROFILE) != 0) && !db->init.busy && p->zSql) { sqlOsCurrentTimeInt64(db->pVfs, &p->startTime); } else { assert(p->startTime == 0); } -#endif db->nVdbeActive++; p->pc = 0; @@ -554,11 +536,9 @@ sqlStep(Vdbe * p) db->nVdbeExec--; } -#ifndef SQL_OMIT_TRACE /* If the statement completed successfully, invoke the profile callback */ if (rc != SQL_ROW) checkProfileCallback(db, p); -#endif db->errCode = rc; if (SQL_NOMEM == sqlApiExit(p->db, p->rc)) { @@ -1097,16 +1077,6 @@ sql_column_datatype(sql_stmt *pStmt, int N) COLNAME_DECLTYPE); } -/* - * Constraint: If you have ENABLE_COLUMN_METADATA then you must - * not define OMIT_DECLTYPE. - */ -#if defined(SQL_OMIT_DECLTYPE) && defined(SQL_ENABLE_COLUMN_METADATA) -#error "Must not define both SQL_OMIT_DECLTYPE \ - and SQL_ENABLE_COLUMN_METADATA" -#endif - -#ifndef SQL_OMIT_DECLTYPE /* * Return the column declaration type (if applicable) of the 'i'th column * of the result set of SQL statement pStmt. @@ -1117,45 +1087,6 @@ sql_column_decltype(sql_stmt * pStmt, int N) return columnName(pStmt, N, (const void *(*)(Mem *))sql_value_text, COLNAME_DECLTYPE); } -#endif /* SQL_OMIT_DECLTYPE */ - -#ifdef SQL_ENABLE_COLUMN_METADATA -/* - * Return the name of the database from which a result column derives. - * NULL is returned if the result column is an expression or constant or - * anything else which is not an unambiguous reference to a database column. - */ -const char * -sql_column_database_name(sql_stmt * pStmt, int N) -{ - return columnName(pStmt, N, (const void *(*)(Mem *))sql_value_text, - COLNAME_DATABASE); -} - -/* - * Return the name of the table from which a result column derives. - * NULL is returned if the result column is an expression or constant or - * anything else which is not an unambiguous reference to a database column. - */ -const char * -sql_column_table_name(sql_stmt * pStmt, int N) -{ - return columnName(pStmt, N, (const void *(*)(Mem *))sql_value_text, - COLNAME_TABLE); -} - -/* - * Return the name of the table column from which a result column derives. - * NULL is returned if the result column is an expression or constant or - * anything else which is not an unambiguous reference to a database column. - */ -const char * -sql_column_origin_name(sql_stmt * pStmt, int N) -{ - return columnName(pStmt, N, (const void *(*)(Mem *))sql_value_text, - COLNAME_COLUMN); -} -#endif /* SQL_ENABLE_COLUMN_METADATA */ /******************************* sql_bind_ ************************** * @@ -1580,16 +1511,10 @@ sql_sql(sql_stmt * pStmt) * bound parameters expanded. Space to hold the returned string is * obtained from sql_malloc(). The caller is responsible for * freeing the returned string by passing it to sql_free(). - * - * The SQL_TRACE_SIZE_LIMIT puts an upper bound on the size of - * expanded bound parameters. */ char * sql_expanded_sql(sql_stmt * pStmt) { -#ifdef SQL_OMIT_TRACE - return 0; -#else char *z = 0; const char *zSql = sql_sql(pStmt); if (zSql) { @@ -1597,79 +1522,5 @@ sql_expanded_sql(sql_stmt * pStmt) z = sqlVdbeExpandSql(p, zSql); } return z; -#endif -} - -#ifdef SQL_ENABLE_STMT_SCANSTATUS -/* - * Return status data for a single loop within query pStmt. - */ -int -sql_stmt_scanstatus(sql_stmt * pStmt, /* Prepared statement being queried */ - int idx, /* Index of loop to report on */ - int iScanStatusOp, /* Which metric to return */ - void *pOut /* OUT: Write the answer here */ - ) -{ - Vdbe *p = (Vdbe *) pStmt; - ScanStatus *pScan; - if (idx < 0 || idx >= p->nScan) - return 1; - pScan = &p->aScan[idx]; - switch (iScanStatusOp) { - case SQL_SCANSTAT_NLOOP:{ - *(sql_int64 *) pOut = p->anExec[pScan->addrLoop]; - break; - } - case SQL_SCANSTAT_NVISIT:{ - *(sql_int64 *) pOut = p->anExec[pScan->addrVisit]; - break; - } - case SQL_SCANSTAT_EST:{ - double r = 1.0; - LogEst x = pScan->nEst; - while (x < 100) { - x += 10; - r *= 0.5; - } - *(double *)pOut = r * sqlLogEstToInt(x); - break; - } - case SQL_SCANSTAT_NAME:{ - *(const char **)pOut = pScan->zName; - break; - } - case SQL_SCANSTAT_EXPLAIN:{ - if (pScan->addrExplain) { - *(const char **)pOut = - p->aOp[pScan->addrExplain].p4.z; - } else { - *(const char **)pOut = 0; - } - break; - } - case SQL_SCANSTAT_SELECTID:{ - if (pScan->addrExplain) { - *(int *)pOut = p->aOp[pScan->addrExplain].p1; - } else { - *(int *)pOut = -1; - } - break; - } - default:{ - return 1; - } - } - return 0; } -/* - * Zero all counters associated with the sql_stmt_scanstatus() data. - */ -void -sql_stmt_scanstatus_reset(sql_stmt * pStmt) -{ - Vdbe *p = (Vdbe *) pStmt; - memset(p->anExec, 0, p->nOp * sizeof(i64)); -} -#endif /* SQL_ENABLE_STMT_SCANSTATUS */ diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c index 25d4cd7598f502d0056c30529946b8e777fddc9b..a90c492fec4c16b8dd8a1ab930824a545488f03b 100644 --- a/src/box/sql/vdbeaux.c +++ b/src/box/sql/vdbeaux.c @@ -137,10 +137,6 @@ sqlVdbeSetSql(Vdbe * p, const char *z, int n, int isPrepareV2) assert(isPrepareV2 == 1 || isPrepareV2 == 0); if (p == 0) return; -#if defined(SQL_OMIT_TRACE) - if (!isPrepareV2) - return; -#endif assert(p->zSql == 0); p->zSql = sqlDbStrNDup(p->db, z, n); p->isPrepareV2 = (u8) isPrepareV2; @@ -747,33 +743,6 @@ sqlVdbeTakeOpArray(Vdbe * p, int *pnOp, int *pnMaxArg) return aOp; } -#if defined(SQL_ENABLE_STMT_SCANSTATUS) -/* - * Add an entry to the array of counters managed by sql_stmt_scanstatus(). - */ -void -sqlVdbeScanStatus(Vdbe * p, /* VM to add scanstatus() to */ - int addrExplain, /* Address of OP_Explain (or 0) */ - int addrLoop, /* Address of loop counter */ - int addrVisit, /* Address of rows visited counter */ - LogEst nEst, /* Estimated number of output rows */ - const char *zName) /* Name of table or index being scanned */ -{ - int nByte = (p->nScan + 1) * sizeof(ScanStatus); - ScanStatus *aNew; - aNew = (ScanStatus *) sqlDbRealloc(p->db, p->aScan, nByte); - if (aNew) { - ScanStatus *pNew = &aNew[p->nScan++]; - pNew->addrExplain = addrExplain; - pNew->addrLoop = addrLoop; - pNew->addrVisit = addrVisit; - pNew->nEst = nEst; - pNew->zName = sqlDbStrDup(p->db, zName); - p->aScan = aNew; - } -} -#endif - /* * Change the value of the opcode, or P1, P2, P3, or P5 operands * for a specific instruction. @@ -1753,40 +1722,6 @@ sqlVdbePrintSql(Vdbe * p) } #endif -#if !defined(SQL_OMIT_TRACE) && defined(SQL_ENABLE_IOTRACE) -/* - * Print an IOTRACE message showing SQL content. - */ -void -sqlVdbeIOTraceSql(Vdbe * p) -{ - int nOp = p->nOp; - VdbeOp *pOp; - if (sqlIoTrace == 0) - return; - if (nOp < 1) - return; - pOp = &p->aOp[0]; - if (pOp->opcode == OP_Init && pOp->p4.z != 0) { - int i, j; - char z[1000]; - sql_snprintf(sizeof(z), z, "%s", pOp->p4.z); - for (i = 0; sqlIsspace(z[i]); i++) { - } - for (j = 0; z[i]; i++) { - if (sqlIsspace(z[i])) { - if (z[i - 1] != ' ') { - z[j++] = ' '; - } - } else { - z[j++] = z[i]; - } - } - z[j] = 0; - sqlIoTrace("SQL %s\n", z); - } -} -#endif /* !SQL_OMIT_TRACE && SQL_ENABLE_IOTRACE */ /* An instance of this object describes bulk memory available for use * by subcomponents of a prepared statement. Space is allocated out @@ -1959,9 +1894,6 @@ sqlVdbeMakeReady(Vdbe * p, /* The VDBE */ p->apArg = allocSpace(&x, p->apArg, nArg * sizeof(Mem *)); p->apCsr = allocSpace(&x, p->apCsr, nCursor * sizeof(VdbeCursor *)); -#ifdef SQL_ENABLE_STMT_SCANSTATUS - p->anExec = allocSpace(&x, p->anExec, p->nOp * sizeof(i64)); -#endif if (x.nNeeded == 0) break; x.pSpace = p->pFree = sqlDbMallocRawNN(db, x.nNeeded); @@ -1982,9 +1914,6 @@ sqlVdbeMakeReady(Vdbe * p, /* The VDBE */ p->nMem = nMem; initMemArray(p->aMem, nMem, db, MEM_Undefined); memset(p->apCsr, 0, nCursor * sizeof(VdbeCursor *)); -#ifdef SQL_ENABLE_STMT_SCANSTATUS - memset(p->anExec, 0, p->nOp * sizeof(i64)); -#endif } sqlVdbeRewind(p); } @@ -2040,9 +1969,6 @@ sqlVdbeFrameRestore(VdbeFrame * pFrame) { Vdbe *v = pFrame->v; closeCursorsInFrame(v); -#ifdef SQL_ENABLE_STMT_SCANSTATUS - v->anExec = pFrame->anExec; -#endif v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; v->aMem = pFrame->aMem; @@ -2727,15 +2653,6 @@ sqlVdbeClearObject(sql * db, Vdbe * p) vdbeFreeOpArray(db, p->aOp, p->nOp); sqlDbFree(db, p->aColName); sqlDbFree(db, p->zSql); -#ifdef SQL_ENABLE_STMT_SCANSTATUS - { - int i; - for (i = 0; i < p->nScan; i++) { - sqlDbFree(db, p->aScan[i].zName); - } - sqlDbFree(db, p->aScan); - } -#endif } /* diff --git a/src/box/sql/vdbesort.c b/src/box/sql/vdbesort.c index 779e832648fb645dcc40543becd8d5ac8e7c5412..3d9d1663c6217f1196fddbd64fd67bc7dedab550 100644 --- a/src/box/sql/vdbesort.c +++ b/src/box/sql/vdbesort.c @@ -118,11 +118,6 @@ * there are already N worker threads running, the main thread does the work * itself. * - * The sorter is running in multi-threaded mode if (a) the library was built - * with pre-processor symbol SQL_MAX_WORKER_THREADS set to a value greater - * than zero, and (b) worker threads have been enabled at runtime by calling - * "PRAGMA threads=N" with some value of N greater than 0. - * * When Rewind() is called, any data remaining in memory is flushed to a * final PMA. So at this point the data is stored in some number of sorted * PMAs within temporary files on disk. @@ -159,15 +154,6 @@ #include "sqlInt.h" #include "vdbeInt.h" -/* - * If SQL_DEBUG_SORTER_THREADS is defined, this module outputs various - * messages to stderr that may be helpful in understanding the performance - * characteristics of the sorter in multi-threaded mode. - */ -#if 0 -#define SQL_DEBUG_SORTER_THREADS 1 -#endif - /* * Hard-coded maximum amount of data to accumulate in memory before flushing * to a level 0 PMA. The purpose of this limit is to prevent various integer @@ -292,31 +278,12 @@ struct MergeEngine { * * Essentially, this structure contains all those fields of the VdbeSorter * structure for which each thread requires a separate instance. For example, - * each thread requries its own UnpackedRecord object to unpack records in + * each thread requires its own UnpackedRecord object to unpack records in * as part of comparison operations. - * - * Before a background thread is launched, variable bDone is set to 0. Then, - * right before it exits, the thread itself sets bDone to 1. This is used for - * two purposes: - * - * 1. When flushing the contents of memory to a level-0 PMA on disk, to - * attempt to select a SortSubtask for which there is not already an - * active background thread (since doing so causes the main thread - * to block until it finishes). - * - * 2. If SQL_DEBUG_SORTER_THREADS is defined, to determine if a call - * to sqlThreadJoin() is likely to block. Cases that are likely to - * block provoke debugging output. - * - * In both cases, the effects of the main thread seeing (bDone==0) even - * after the thread has finished are not dire. So we don't worry about - * memory barriers and such here. */ typedef int (*SorterCompare) (SortSubtask *, bool *, const void *, const void *); struct SortSubtask { - sqlThread *pThread; /* Background thread, if any */ - int bDone; /* Set if thread is finished but not joined */ VdbeSorter *pSorter; /* Sorter that owns this sub-task */ UnpackedRecord *pUnpacked; /* Space to unpack a record */ SorterList list; /* List for thread to write to a PMA */ @@ -349,11 +316,8 @@ struct VdbeSorter { int iMemory; /* Offset of free space in list.aMemory */ int nMemory; /* Size of list.aMemory allocation in bytes */ u8 bUsePMA; /* True if one or more PMAs created */ - u8 bUseThreads; /* True to use background threads */ - u8 iPrev; /* Previous thread used to flush PMA */ - u8 nTask; /* Size of aTask[] array */ u8 typeMask; - SortSubtask aTask[1]; /* One or more subtasks */ + SortSubtask aTask; /* A single subtask */ }; #define SORTER_TYPE_INTEGER 0x01 @@ -852,28 +816,8 @@ sqlVdbeSorterInit(sql * db, /* Database connection (for malloc()) */ ) { int pgsz; /* Page size of main database */ - int i; /* Used to iterate through aTask[] */ VdbeSorter *pSorter; /* The new sorter */ int rc = SQL_OK; -#if SQL_MAX_WORKER_THREADS==0 -#define nWorker 0 -#else - int nWorker; -#endif - - /* Initialize the upper limit on the number of worker threads */ -#if SQL_MAX_WORKER_THREADS>0 - nWorker = db->aLimit[SQL_LIMIT_WORKER_THREADS]; -#endif - - /* Do not allow the total number of threads (main thread + all workers) - * to exceed the maximum merge count - */ -#if SQL_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT - if (nWorker >= SORTER_MAX_MERGE_COUNT) { - nWorker = SORTER_MAX_MERGE_COUNT - 1; - } -#endif assert(pCsr->key_def != NULL); assert(pCsr->eCurType == CURTYPE_SORTER); @@ -885,38 +829,30 @@ sqlVdbeSorterInit(sql * db, /* Database connection (for malloc()) */ } else { pSorter->key_def = pCsr->key_def; pSorter->pgsz = pgsz = 1024; - pSorter->nTask = nWorker + 1; - pSorter->iPrev = (u8) (nWorker - 1); - pSorter->bUseThreads = (pSorter->nTask > 1); pSorter->db = db; - for (i = 0; i < pSorter->nTask; i++) { - SortSubtask *pTask = &pSorter->aTask[i]; - pTask->pSorter = pSorter; - } + pSorter->aTask.pSorter = pSorter; - if (!sqlTempInMemory(db)) { - i64 mxCache; /* Cache size in bytes */ - u32 szPma = sqlGlobalConfig.szPma; - pSorter->mnPmaSize = szPma * pgsz; + i64 mxCache; /* Cache size in bytes */ + u32 szPma = sqlGlobalConfig.szPma; + pSorter->mnPmaSize = szPma * pgsz; - mxCache = SQL_DEFAULT_CACHE_SIZE; - mxCache = mxCache * -1024; - mxCache = MIN(mxCache, SQL_MAX_PMASZ); - pSorter->mxPmaSize = - MAX(pSorter->mnPmaSize, (int)mxCache); + mxCache = SQL_DEFAULT_CACHE_SIZE; + mxCache = mxCache * -1024; + mxCache = MIN(mxCache, SQL_MAX_PMASZ); + pSorter->mxPmaSize = + MAX(pSorter->mnPmaSize, (int)mxCache); - /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of - * scratch memory using SQL_CONFIG_SCRATCH, sql avoids unnecessary - * large heap allocations. - */ - if (sqlGlobalConfig.pScratch == 0) { - assert(pSorter->iMemory == 0); - pSorter->nMemory = pgsz; - pSorter->list.aMemory = - (u8 *) sqlMalloc(pgsz); - if (!pSorter->list.aMemory) - rc = SQL_NOMEM; - } + /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of + * scratch memory using SQL_CONFIG_SCRATCH, sql avoids unnecessary + * large heap allocations. + */ + if (sqlGlobalConfig.pScratch == 0) { + assert(pSorter->iMemory == 0); + pSorter->nMemory = pgsz; + pSorter->list.aMemory = + (u8 *) sqlMalloc(pgsz); + if (!pSorter->list.aMemory) + rc = SQL_NOMEM; } if (pCsr->key_def->part_count < 13 @@ -929,8 +865,6 @@ sqlVdbeSorterInit(sql * db, /* Database connection (for malloc()) */ return rc; } -#undef nWorker /* Defined at the top of this function */ - /* * Free the list of sorted records starting at pRecord. */ @@ -953,18 +887,10 @@ static void vdbeSortSubtaskCleanup(sql * db, SortSubtask * pTask) { sqlDbFree(db, pTask->pUnpacked); -#if SQL_MAX_WORKER_THREADS>0 - /* pTask->list.aMemory can only be non-zero if it was handed memory - * from the main thread. That only occurs SQL_MAX_WORKER_THREADS>0 - */ - if (pTask->list.aMemory) { - sql_free(pTask->list.aMemory); - } else -#endif - { - assert(pTask->list.aMemory == 0); - vdbeSorterRecordFree(0, pTask->list.pList); - } + + assert(pTask->list.aMemory == 0); + vdbeSorterRecordFree(0, pTask->list.pList); + if (pTask->file.pFd) { sqlOsCloseFree(pTask->file.pFd); } @@ -974,116 +900,7 @@ vdbeSortSubtaskCleanup(sql * db, SortSubtask * pTask) memset(pTask, 0, sizeof(SortSubtask)); } -#ifdef SQL_DEBUG_SORTER_THREADS -static void -vdbeSorterWorkDebug(SortSubtask * pTask, const char *zEvent) -{ - i64 t; - int iTask = (pTask - pTask->pSorter->aTask); - sqlOsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); - fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); -} - -static void -vdbeSorterRewindDebug(const char *zEvent) -{ - i64 t; - sqlOsCurrentTimeInt64(sql_vfs_find(0), &t); - fprintf(stderr, "%lld:X %s\n", t, zEvent); -} - -static void -vdbeSorterPopulateDebug(SortSubtask * pTask, const char *zEvent) -{ - i64 t; - int iTask = (pTask - pTask->pSorter->aTask); - sqlOsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); - fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent); -} - -static void -vdbeSorterBlockDebug(SortSubtask * pTask, int bBlocked, const char *zEvent) -{ - if (bBlocked) { - i64 t; - sqlOsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); - fprintf(stderr, "%lld:main %s\n", t, zEvent); - } -} -#else -#define vdbeSorterWorkDebug(x,y) -#define vdbeSorterRewindDebug(y) -#define vdbeSorterPopulateDebug(x,y) -#define vdbeSorterBlockDebug(x,y,z) -#endif - -#if SQL_MAX_WORKER_THREADS>0 -/* - * Join thread pTask->thread. - */ -static int -vdbeSorterJoinThread(SortSubtask * pTask) -{ - int rc = SQL_OK; - if (pTask->pThread) { -#ifdef SQL_DEBUG_SORTER_THREADS - int bDone = pTask->bDone; -#endif - void *pRet = SQL_INT_TO_PTR(SQL_ERROR); - vdbeSorterBlockDebug(pTask, !bDone, "enter"); - (void)sqlThreadJoin(pTask->pThread, &pRet); - vdbeSorterBlockDebug(pTask, !bDone, "exit"); - rc = SQL_PTR_TO_INT(pRet); - assert(pTask->bDone == 1); - pTask->bDone = 0; - pTask->pThread = 0; - } - return rc; -} - -/* - * Launch a background thread to run xTask(pIn). - */ -static int -vdbeSorterCreateThread(SortSubtask * pTask, /* Thread will use this task object */ - void *(*xTask) (void *), /* Routine to run in a separate thread */ - void *pIn /* Argument passed into xTask() */ - ) -{ - assert(pTask->pThread == 0 && pTask->bDone == 0); - return sqlThreadCreate(&pTask->pThread, xTask, pIn); -} - -/* - * Join all outstanding threads launched by SorterWrite() to create - * level-0 PMAs. - */ -static int -vdbeSorterJoinAll(VdbeSorter * pSorter, int rcin) -{ - int rc = rcin; - int i; - - /* This function is always called by the main user thread. - * - * If this function is being called after SorterRewind() has been called, - * it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread - * is currently attempt to join one of the other threads. To avoid a race - * condition where this thread also attempts to join the same object, join - * thread pSorter->aTask[pSorter->nTask-1].pThread first. - */ - for (i = pSorter->nTask - 1; i >= 0; i--) { - SortSubtask *pTask = &pSorter->aTask[i]; - int rc2 = vdbeSorterJoinThread(pTask); - if (rc == SQL_OK) - rc = rc2; - } - return rc; -} -#else #define vdbeSorterJoinAll(x,rcin) (rcin) -#define vdbeSorterJoinThread(pTask) SQL_OK -#endif /* * Allocate a new MergeEngine object capable of handling up to @@ -1139,15 +956,6 @@ static void vdbeIncrFree(IncrMerger * pIncr) { if (pIncr) { -#if SQL_MAX_WORKER_THREADS>0 - if (pIncr->bUseThread) { - vdbeSorterJoinThread(pIncr->pTask); - if (pIncr->aFile[0].pFd) - sqlOsCloseFree(pIncr->aFile[0].pFd); - if (pIncr->aFile[1].pFd) - sqlOsCloseFree(pIncr->aFile[1].pFd); - } -#endif vdbeMergeEngineFree(pIncr->pMerger); sql_free(pIncr); } @@ -1159,23 +967,12 @@ vdbeIncrFree(IncrMerger * pIncr) void sqlVdbeSorterReset(sql * db, VdbeSorter * pSorter) { - int i; (void)vdbeSorterJoinAll(pSorter, SQL_OK); - assert(pSorter->bUseThreads || pSorter->pReader == 0); -#if SQL_MAX_WORKER_THREADS>0 - if (pSorter->pReader) { - vdbePmaReaderClear(pSorter->pReader); - sqlDbFree(db, pSorter->pReader); - pSorter->pReader = 0; - } -#endif + assert(pSorter->pReader == 0); vdbeMergeEngineFree(pSorter->pMerger); pSorter->pMerger = 0; - for (i = 0; i < pSorter->nTask; i++) { - SortSubtask *pTask = &pSorter->aTask[i]; - vdbeSortSubtaskCleanup(db, pTask); - pTask->pSorter = pSorter; - } + vdbeSortSubtaskCleanup(db, &pSorter->aTask); + pSorter->aTask.pSorter = pSorter; if (pSorter->list.aMemory == 0) { vdbeSorterRecordFree(0, pSorter->list.pList); } @@ -1518,7 +1315,6 @@ vdbeSorterListToPMA(SortSubtask * pTask, SorterList * pList) pList->szPMA + sqlVarintLen(pList->szPMA) + pTask->file.iEof; #endif - vdbeSorterWorkDebug(pTask, "enter"); memset(&writer, 0, sizeof(PmaWriter)); assert(pList->szPMA > 0); @@ -1560,7 +1356,6 @@ vdbeSorterListToPMA(SortSubtask * pTask, SorterList * pList) rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof); } - vdbeSorterWorkDebug(pTask, "exit"); assert(rc != SQL_OK || pList->pList == 0); assert(rc != SQL_OK || pTask->file.iEof == iSz); return rc; @@ -1650,22 +1445,6 @@ vdbeMergeEngineStep(MergeEngine * pMerger, /* The merge engine to advance to the return (rc == SQL_OK ? pTask->pUnpacked->errCode : rc); } -#if SQL_MAX_WORKER_THREADS>0 -/* - * The main routine for background threads that write level-0 PMAs. - */ -static void * -vdbeSorterFlushThread(void *pCtx) -{ - SortSubtask *pTask = (SortSubtask *) pCtx; - int rc; /* Return code */ - assert(pTask->bDone == 0); - rc = vdbeSorterListToPMA(pTask, &pTask->list); - pTask->bDone = 1; - return SQL_INT_TO_PTR(rc); -} -#endif /* SQL_MAX_WORKER_THREADS>0 */ - /* * Flush the current contents of VdbeSorter.list to a new PMA, possibly * using a background thread. @@ -1673,76 +1452,8 @@ vdbeSorterFlushThread(void *pCtx) static int vdbeSorterFlushPMA(VdbeSorter * pSorter) { -#if SQL_MAX_WORKER_THREADS==0 pSorter->bUsePMA = 1; - return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list); -#else - int rc = SQL_OK; - int i; - SortSubtask *pTask = 0; /* Thread context used to create new PMA */ - int nWorker = (pSorter->nTask - 1); - - /* Set the flag to indicate that at least one PMA has been written. - * Or will be, anyhow. - */ - pSorter->bUsePMA = 1; - - /* Select a sub-task to sort and flush the current list of in-memory - * records to disk. If the sorter is running in multi-threaded mode, - * round-robin between the first (pSorter->nTask-1) tasks. Except, if - * the background thread from a sub-tasks previous turn is still running, - * skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, - * fall back to using the final sub-task. The first (pSorter->nTask-1) - * sub-tasks are prefered as they use background threads - the final - * sub-task uses the main thread. - */ - for (i = 0; i < nWorker; i++) { - int iTest = (pSorter->iPrev + i + 1) % nWorker; - pTask = &pSorter->aTask[iTest]; - if (pTask->bDone) { - rc = vdbeSorterJoinThread(pTask); - } - if (rc != SQL_OK || pTask->pThread == 0) - break; - } - - if (rc == SQL_OK) { - if (i == nWorker) { - /* Use the foreground thread for this operation */ - rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], - &pSorter->list); - } else { - /* Launch a background thread for this operation */ - u8 *aMem = pTask->list.aMemory; - void *pCtx = (void *)pTask; - - assert(pTask->pThread == 0 && pTask->bDone == 0); - assert(pTask->list.pList == 0); - assert(pTask->list.aMemory == 0 - || pSorter->list.aMemory != 0); - - pSorter->iPrev = (u8) (pTask - pSorter->aTask); - pTask->list = pSorter->list; - pSorter->list.pList = 0; - pSorter->list.szPMA = 0; - if (aMem) { - pSorter->list.aMemory = aMem; - pSorter->nMemory = sqlMallocSize(aMem); - } else if (pSorter->list.aMemory) { - pSorter->list.aMemory = - sqlMalloc(pSorter->nMemory); - if (!pSorter->list.aMemory) - return SQL_NOMEM; - } - - rc = vdbeSorterCreateThread(pTask, - vdbeSorterFlushThread, - pCtx); - } - } - - return rc; -#endif /* SQL_MAX_WORKER_THREADS!=0 */ + return vdbeSorterListToPMA(&pSorter->aTask, &pSorter->list); } /* @@ -1878,8 +1589,6 @@ vdbeIncrPopulate(IncrMerger * pIncr) PmaWriter writer; assert(pIncr->bEof == 0); - vdbeSorterPopulateDebug(pTask, "enter"); - vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart); while (rc == SQL_OK) { int dummy; @@ -1906,36 +1615,9 @@ vdbeIncrPopulate(IncrMerger * pIncr) rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof); if (rc == SQL_OK) rc = rc2; - vdbeSorterPopulateDebug(pTask, "exit"); return rc; } -#if SQL_MAX_WORKER_THREADS>0 -/* - * The main routine for background threads that populate aFile[1] of - * multi-threaded IncrMerger objects. - */ -static void * -vdbeIncrPopulateThread(void *pCtx) -{ - IncrMerger *pIncr = (IncrMerger *) pCtx; - void *pRet = SQL_INT_TO_PTR(vdbeIncrPopulate(pIncr)); - pIncr->pTask->bDone = 1; - return pRet; -} - -/* - * Launch a background thread to populate aFile[1] of pIncr. - */ -static int -vdbeIncrBgPopulate(IncrMerger * pIncr) -{ - void *p = (void *)pIncr; - assert(pIncr->bUseThread); - return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p); -} -#endif - /* * This function is called when the PmaReader corresponding to pIncr has * finished reading the contents of aFile[0]. Its purpose is to "refill" @@ -1956,33 +1638,10 @@ vdbeIncrBgPopulate(IncrMerger * pIncr) static int vdbeIncrSwap(IncrMerger * pIncr) { - int rc = SQL_OK; - -#if SQL_MAX_WORKER_THREADS>0 - if (pIncr->bUseThread) { - rc = vdbeSorterJoinThread(pIncr->pTask); - - if (rc == SQL_OK) { - SorterFile f0 = pIncr->aFile[0]; - pIncr->aFile[0] = pIncr->aFile[1]; - pIncr->aFile[1] = f0; - } - - if (rc == SQL_OK) { - if (pIncr->aFile[0].iEof == pIncr->iStartOff) { - pIncr->bEof = 1; - } else { - rc = vdbeIncrBgPopulate(pIncr); - } - } - } else -#endif - { - rc = vdbeIncrPopulate(pIncr); - pIncr->aFile[0] = pIncr->aFile[1]; - if (pIncr->aFile[0].iEof == pIncr->iStartOff) { - pIncr->bEof = 1; - } + int rc = vdbeIncrPopulate(pIncr); + pIncr->aFile[0] = pIncr->aFile[1]; + if (pIncr->aFile[0].iEof == pIncr->iStartOff) { + pIncr->bEof = 1; } return rc; @@ -2017,18 +1676,6 @@ vdbeIncrMergerNew(SortSubtask * pTask, /* The thread that will be using the new return rc; } -#if SQL_MAX_WORKER_THREADS>0 -/* - * Set the "use-threads" flag on object pIncr. - */ -static void -vdbeIncrMergerSetThreads(IncrMerger * pIncr) -{ - pIncr->bUseThread = 1; - pIncr->pTask->file2.iEof -= pIncr->mxSz; -} -#endif /* SQL_MAX_WORKER_THREADS>0 */ - /* * Recompute pMerger->aTree[iOut] by comparing the next keys on the * two PmaReaders that feed that entry. Neither of the PmaReaders @@ -2079,38 +1726,20 @@ vdbeMergeEngineCompare(MergeEngine * pMerger, /* Merge engine containing PmaRead pMerger->aTree[iOut] = iRes; } -/* - * Allowed values for the eMode parameter to vdbeMergeEngineInit() - * and vdbePmaReaderIncrMergeInit(). - * - * Only INCRINIT_NORMAL is valid in single-threaded builds (when - * SQL_MAX_WORKER_THREADS==0). The other values are only used - * when there exists one or more separate worker threads. - */ -#define INCRINIT_NORMAL 0 -#define INCRINIT_TASK 1 -#define INCRINIT_ROOT 2 - /* * Forward reference required as the vdbeIncrMergeInit() and * vdbePmaReaderIncrInit() routines are called mutually recursively when * building a merge tree. */ -static int vdbePmaReaderIncrInit(PmaReader * pReadr, int eMode); +static int vdbePmaReaderIncrInit(PmaReader * pReader); /* * Initialize the MergeEngine object passed as the second argument. Once this * function returns, the first key of merged data may be read from the * MergeEngine object in the usual fashion. * - * If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge - * objects attached to the PmaReader objects that the merger reads from have - * already been populated, but that they have not yet populated aFile[0] and - * set the PmaReader objects up to read from it. In this case all that is - * required is to call vdbePmaReaderNext() on each PmaReader to point it at - * its first key. * - * Otherwise, if eMode is any value other than INCRINIT_ROOT, then use + * Use * vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data * to pMerger. * @@ -2118,36 +1747,19 @@ static int vdbePmaReaderIncrInit(PmaReader * pReadr, int eMode); */ static int vdbeMergeEngineInit(SortSubtask * pTask, /* Thread that will run pMerger */ - MergeEngine * pMerger, /* MergeEngine to initialize */ - int eMode /* One of the INCRINIT_XXX constants */ + MergeEngine * pMerger /* MergeEngine to initialize */ ) { int rc = SQL_OK; /* Return code */ int i; /* For looping over PmaReader objects */ int nTree = pMerger->nTree; - /* eMode is always INCRINIT_NORMAL in single-threaded mode */ - assert(SQL_MAX_WORKER_THREADS > 0 || eMode == INCRINIT_NORMAL); - /* Verify that the MergeEngine is assigned to a single thread */ assert(pMerger->pTask == 0); pMerger->pTask = pTask; for (i = 0; i < nTree; i++) { - if (SQL_MAX_WORKER_THREADS > 0 && eMode == INCRINIT_ROOT) { - /* PmaReaders should be normally initialized in order, as if they are - * reading from the same temp file this makes for more linear file IO. - * However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is - * in use it will block the vdbePmaReaderNext() call while it uses - * the main thread to fill its buffer. So calling PmaReaderNext() - * on this PmaReader before any of the multi-threaded PmaReaders takes - * better advantage of multi-processor hardware. - */ - rc = vdbePmaReaderNext(&pMerger->aReadr[nTree - i - 1]); - } else { - rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], - INCRINIT_NORMAL); - } + rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i]); if (rc != SQL_OK) return rc; } @@ -2159,50 +1771,27 @@ vdbeMergeEngineInit(SortSubtask * pTask, /* Thread that will run pMerger */ } /* - * The PmaReader passed as the first argument is guaranteed to be an + * The PmaReader is guaranteed to be an * incremental-reader (pReadr->pIncr!=0). This function serves to open * and/or initialize the temp file related fields of the IncrMerge * object at (pReadr->pIncr). * - * If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders - * in the sub-tree headed by pReadr are also initialized. Data is then + * All PmaReaders + * in the sub-tree headed by pReadr are also initialized. Data is * loaded into the buffers belonging to pReadr and it is set to point to * the first key in its range. * - * If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed - * to be a multi-threaded PmaReader and this function is being called in a - * background thread. In this case all PmaReaders in the sub-tree are - * initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to - * pReadr is populated. However, pReadr itself is not set up to point - * to its first key. A call to vdbePmaReaderNext() is still required to do - * that. - * - * The reason this function does not call vdbePmaReaderNext() immediately - * in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has - * to block on thread (pTask->thread) before accessing aFile[1]. But, since - * this entire function is being run by thread (pTask->thread), that will - * lead to the current background thread attempting to join itself. - * - * Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed - * that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all - * child-trees have already been initialized using IncrInit(INCRINIT_TASK). - * In this case vdbePmaReaderNext() is called on all child PmaReaders and - * the current PmaReader set to point to the first key in its range. - * * SQL_OK is returned if successful, or an sql error code otherwise. */ static int -vdbePmaReaderIncrMergeInit(PmaReader * pReadr, int eMode) +vdbePmaReaderIncrMergeInit(PmaReader * pReadr) { int rc = SQL_OK; IncrMerger *pIncr = pReadr->pIncr; SortSubtask *pTask = pIncr->pTask; sql *db = pTask->pSorter->db; - /* eMode is always INCRINIT_NORMAL in single-threaded mode */ - assert(SQL_MAX_WORKER_THREADS > 0 || eMode == INCRINIT_NORMAL); - - rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); + rc = vdbeMergeEngineInit(pTask, pIncr->pMerger); /* Set up the required files for pIncr. A multi-theaded IncrMerge object * requires two temp files to itself, whereas a single-threaded object @@ -2210,74 +1799,27 @@ vdbePmaReaderIncrMergeInit(PmaReader * pReadr, int eMode) */ if (rc == SQL_OK) { int mxSz = pIncr->mxSz; -#if SQL_MAX_WORKER_THREADS>0 - if (pIncr->bUseThread) { - rc = vdbeSorterOpenTempFile(db, mxSz, - &pIncr->aFile[0].pFd); - if (rc == SQL_OK) { - rc = vdbeSorterOpenTempFile(db, mxSz, - &pIncr->aFile[1]. - pFd); - } - } else -#endif - /*if( !pIncr->bUseThread ) */ { - if (pTask->file2.pFd == 0) { - assert(pTask->file2.iEof > 0); - rc = vdbeSorterOpenTempFile(db, - pTask->file2.iEof, - &pTask->file2.pFd); - pTask->file2.iEof = 0; - } - if (rc == SQL_OK) { - pIncr->aFile[1].pFd = pTask->file2.pFd; - pIncr->iStartOff = pTask->file2.iEof; - pTask->file2.iEof += mxSz; - } - } - } -#if SQL_MAX_WORKER_THREADS>0 - if (rc == SQL_OK && pIncr->bUseThread) { - /* Use the current thread to populate aFile[1], even though this - * PmaReader is multi-threaded. If this is an INCRINIT_TASK object, - * then this function is already running in background thread - * pIncr->pTask->thread. - * - * If this is the INCRINIT_ROOT object, then it is running in the - * main VDBE thread. But that is Ok, as that thread cannot return - * control to the VDBE or proceed with anything useful until the - * first results are ready from this merger object anyway. - */ - assert(eMode == INCRINIT_ROOT || eMode == INCRINIT_TASK); - rc = vdbeIncrPopulate(pIncr); + if (pTask->file2.pFd == 0) { + assert(pTask->file2.iEof > 0); + rc = vdbeSorterOpenTempFile(db, + pTask->file2.iEof, + &pTask->file2.pFd); + pTask->file2.iEof = 0; + } + if (rc == SQL_OK) { + pIncr->aFile[1].pFd = pTask->file2.pFd; + pIncr->iStartOff = pTask->file2.iEof; + pTask->file2.iEof += mxSz; + } } -#endif - if (rc == SQL_OK - && (SQL_MAX_WORKER_THREADS == 0 || eMode != INCRINIT_TASK)) { + if (rc == SQL_OK) { rc = vdbePmaReaderNext(pReadr); } return rc; } -#if SQL_MAX_WORKER_THREADS>0 -/* - * The main routine for vdbePmaReaderIncrMergeInit() operations run in - * background threads. - */ -static void * -vdbePmaReaderBgIncrInit(void *pCtx) -{ - PmaReader *pReader = (PmaReader *) pCtx; - void *pRet = - SQL_INT_TO_PTR(vdbePmaReaderIncrMergeInit(pReader, INCRINIT_TASK) - ); - pReader->pIncr->pTask->bDone = 1; - return pRet; -} -#endif - /* * If the PmaReader passed as the first argument is not an incremental-reader * (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes @@ -2290,23 +1832,12 @@ vdbePmaReaderBgIncrInit(void *pCtx) * using the current thread. */ static int -vdbePmaReaderIncrInit(PmaReader * pReadr, int eMode) +vdbePmaReaderIncrInit(PmaReader * pReadr) { IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */ int rc = SQL_OK; /* Return code */ if (pIncr) { -#if SQL_MAX_WORKER_THREADS>0 - assert(pIncr->bUseThread == 0 || eMode == INCRINIT_TASK); - if (pIncr->bUseThread) { - void *pCtx = (void *)pReadr; - rc = vdbeSorterCreateThread(pIncr->pTask, - vdbePmaReaderBgIncrInit, - pCtx); - } else -#endif - { - rc = vdbePmaReaderIncrMergeInit(pReadr, eMode); - } + rc = vdbePmaReaderIncrMergeInit(pReadr); } return rc; } @@ -2451,77 +1982,51 @@ vdbeSorterMergeTreeBuild(VdbeSorter * pSorter, /* The VDBE cursor that implement { MergeEngine *pMain = 0; int rc = SQL_OK; - int iTask; -#if SQL_MAX_WORKER_THREADS>0 - /* If the sorter uses more than one task, then create the top-level - * MergeEngine here. This MergeEngine will read data from exactly - * one PmaReader per sub-task. - */ - assert(pSorter->bUseThreads || pSorter->nTask == 1); - if (pSorter->nTask > 1) { - pMain = vdbeMergeEngineNew(pSorter->nTask); - if (pMain == 0) - rc = SQL_NOMEM; - } -#endif + SortSubtask *pTask = &pSorter->aTask; + assert(pTask->nPMA > 0); + if (pTask->nPMA) { + MergeEngine *pRoot = 0; /* Root node of tree for this task */ + int nDepth = vdbeSorterTreeDepth(pTask->nPMA); + i64 iReadOff = 0; - for (iTask = 0; rc == SQL_OK && iTask < pSorter->nTask; iTask++) { - SortSubtask *pTask = &pSorter->aTask[iTask]; - assert(pTask->nPMA > 0 || SQL_MAX_WORKER_THREADS > 0); - if (SQL_MAX_WORKER_THREADS == 0 || pTask->nPMA) { - MergeEngine *pRoot = 0; /* Root node of tree for this task */ - int nDepth = vdbeSorterTreeDepth(pTask->nPMA); - i64 iReadOff = 0; - - if (pTask->nPMA <= SORTER_MAX_MERGE_COUNT) { - rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, - &iReadOff, &pRoot); - } else { - int i; - int iSeq = 0; - pRoot = - vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); - if (pRoot == 0) - rc = SQL_NOMEM; - for (i = 0; i < pTask->nPMA && rc == SQL_OK; - i += SORTER_MAX_MERGE_COUNT) { - MergeEngine *pMerger = 0; /* New level-0 PMA merger */ - int nReader; /* Number of level-0 PMAs to merge */ - - nReader = - MIN(pTask->nPMA - i, - SORTER_MAX_MERGE_COUNT); - rc = vdbeMergeEngineLevel0(pTask, - nReader, - &iReadOff, - &pMerger); - if (rc == SQL_OK) { - rc = vdbeSorterAddToTree(pTask, - nDepth, - iSeq++, - pRoot, - pMerger); - } + if (pTask->nPMA <= SORTER_MAX_MERGE_COUNT) { + rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, + &iReadOff, &pRoot); + } else { + int i; + int iSeq = 0; + pRoot = + vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); + if (pRoot == 0) + rc = SQL_NOMEM; + for (i = 0; i < pTask->nPMA && rc == SQL_OK; + i += SORTER_MAX_MERGE_COUNT) { + MergeEngine *pMerger = 0; /* New level-0 PMA merger */ + int nReader; /* Number of level-0 PMAs to merge */ + + nReader = + MIN(pTask->nPMA - i, + SORTER_MAX_MERGE_COUNT); + rc = vdbeMergeEngineLevel0(pTask, + nReader, + &iReadOff, + &pMerger); + if (rc == SQL_OK) { + rc = vdbeSorterAddToTree(pTask, + nDepth, + iSeq++, + pRoot, + pMerger); } } + } - if (rc == SQL_OK) { -#if SQL_MAX_WORKER_THREADS>0 - if (pMain != 0) { - rc = vdbeIncrMergerNew(pTask, pRoot, - &pMain-> - aReadr[iTask]. - pIncr); - } else -#endif - { - assert(pMain == 0); - pMain = pRoot; - } - } else { - vdbeMergeEngineFree(pRoot); - } + if (rc == SQL_OK) { + assert(pMain == 0); + pMain = pRoot; + } else { + vdbeMergeEngineFree(pRoot); } } @@ -2546,90 +2051,13 @@ static int vdbeSorterSetupMerge(VdbeSorter * pSorter) { int rc; /* Return code */ - SortSubtask *pTask0 = &pSorter->aTask[0]; MergeEngine *pMain = 0; -#if SQL_MAX_WORKER_THREADS - sql *db = pTask0->pSorter->db; - int i; - SorterCompare xCompare = vdbeSorterGetCompare(pSorter); - for (i = 0; i < pSorter->nTask; i++) { - pSorter->aTask[i].xCompare = xCompare; - } -#endif rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); if (rc == SQL_OK) { -#if SQL_MAX_WORKER_THREADS - assert(pSorter->bUseThreads == 0 || pSorter->nTask > 1); - if (pSorter->bUseThreads) { - int iTask; - PmaReader *pReadr = 0; - SortSubtask *pLast = - &pSorter->aTask[pSorter->nTask - 1]; - rc = vdbeSortAllocUnpacked(pLast); - if (rc == SQL_OK) { - pReadr = - (PmaReader *) sqlDbMallocZero(db, - sizeof - (PmaReader)); - pSorter->pReader = pReadr; - if (pReadr == 0) - rc = SQL_NOMEM; - } - if (rc == SQL_OK) { - rc = vdbeIncrMergerNew(pLast, pMain, - &pReadr->pIncr); - if (rc == SQL_OK) { - vdbeIncrMergerSetThreads(pReadr->pIncr); - for (iTask = 0; - iTask < (pSorter->nTask - 1); - iTask++) { - IncrMerger *pIncr; - if ((pIncr = - pMain->aReadr[iTask]. - pIncr)) { - vdbeIncrMergerSetThreads - (pIncr); - assert(pIncr->pTask != - pLast); - } - } - for (iTask = 0; - rc == SQL_OK - && iTask < pSorter->nTask; - iTask++) { - /* Check that: - * - * a) The incremental merge object is configured to use the - * right task, and - * b) If it is using task (nTask-1), it is configured to run - * in single-threaded mode. This is important, as the - * root merge (INCRINIT_ROOT) will be using the same task - * object. - */ - PmaReader *p = - &pMain->aReadr[iTask]; - assert(p->pIncr == 0 || ((p->pIncr->pTask == &pSorter->aTask[iTask]) /* a */ - &&(iTask != pSorter->nTask - 1 || p->pIncr->bUseThread == 0) /* b */ - )); - rc = vdbePmaReaderIncrInit(p, - INCRINIT_TASK); - } - } - pMain = 0; - } - if (rc == SQL_OK) { - rc = vdbePmaReaderIncrMergeInit(pReadr, - INCRINIT_ROOT); - } - } else -#endif - { - rc = vdbeMergeEngineInit(pTask0, pMain, - INCRINIT_NORMAL); - pSorter->pMerger = pMain; - pMain = 0; - } + rc = vdbeMergeEngineInit(&pSorter->aTask, pMain); + pSorter->pMerger = pMain; + pMain = 0; } if (rc != SQL_OK) { @@ -2660,7 +2088,7 @@ sqlVdbeSorterRewind(const VdbeCursor * pCsr, int *pbEof) if (pSorter->bUsePMA == 0) { if (pSorter->list.pList) { *pbEof = 0; - rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list); + rc = vdbeSorterSort(&pSorter->aTask, &pSorter->list); } else { *pbEof = 1; } @@ -2678,8 +2106,6 @@ sqlVdbeSorterRewind(const VdbeCursor * pCsr, int *pbEof) /* Join all threads */ rc = vdbeSorterJoinAll(pSorter, rc); - vdbeSorterRewindDebug("rewind"); - /* Assuming no errors have occurred, set up a merger structure to * incrementally read and merge all remaining PMAs. */ @@ -2689,7 +2115,6 @@ sqlVdbeSorterRewind(const VdbeCursor * pCsr, int *pbEof) *pbEof = 0; } - vdbeSorterRewindDebug("rewinddone"); return rc; } @@ -2708,19 +2133,9 @@ sqlVdbeSorterNext(sql * db, const VdbeCursor * pCsr, int *pbEof) || (pSorter->pReader == 0 && pSorter->pMerger == 0)); if (pSorter->bUsePMA) { assert(pSorter->pReader == 0 || pSorter->pMerger == 0); - assert(pSorter->bUseThreads == 0 || pSorter->pReader); - assert(pSorter->bUseThreads == 1 || pSorter->pMerger); -#if SQL_MAX_WORKER_THREADS>0 - if (pSorter->bUseThreads) { - rc = vdbePmaReaderNext(pSorter->pReader); - *pbEof = (pSorter->pReader->pFd == 0); - } else -#endif - /*if( !pSorter->bUseThreads ) */ { - assert(pSorter->pMerger != 0); - assert(pSorter->pMerger->pTask == (&pSorter->aTask[0])); - rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); - } + assert(pSorter->pMerger); + assert(pSorter->pMerger->pTask == &pSorter->aTask); + rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); } else { SorterRecord *pFree = pSorter->list.pList; pSorter->list.pList = pFree->u.pNext; @@ -2745,11 +2160,6 @@ vdbeSorterRowkey(const VdbeSorter * pSorter, /* Sorter object */ void *pKey; if (pSorter->bUsePMA) { PmaReader *pReader; -#if SQL_MAX_WORKER_THREADS>0 - if (pSorter->bUseThreads) { - pReader = pSorter->pReader; - } else -#endif /*if( !pSorter->bUseThreads ) */ { pReader = &pSorter->pMerger->aReadr[pSorter->pMerger-> diff --git a/src/box/sql/vdbetrace.c b/src/box/sql/vdbetrace.c index cb930538d349212cabbd37e90c55be83ca6d1ea3..f78d5b09342c2f75af783a8082035185985598cf 100644 --- a/src/box/sql/vdbetrace.c +++ b/src/box/sql/vdbetrace.c @@ -39,8 +39,6 @@ #include "sqlInt.h" #include "vdbeInt.h" -#ifndef SQL_OMIT_TRACE - /* * zSql is a zero-terminated string of UTF-8 SQL text. Return the number of * bytes in this text up to but excluding the first character in @@ -77,11 +75,6 @@ findNextHostParameter(const char *zSql, int *pnToken) * then the returned string holds a copy of zRawSql with "-- " prepended * to each line of text. * - * If the SQL_TRACE_SIZE_LIMIT macro is defined to an integer, then - * then long strings and blobs are truncated to that many bytes. This - * can be used to prevent unreasonably large trace strings when dealing - * with large (multi-megabyte) strings and blobs. - * * The calling function is responsible for making sure the memory returned * is eventually freed. * @@ -163,23 +156,7 @@ sqlVdbeExpandSql(Vdbe * p, /* The prepared statement being evaluated */ } else if (pVar->flags & MEM_Str) { int nOut; /* Number of bytes of the string text to include in output */ nOut = pVar->n; -#ifdef SQL_TRACE_SIZE_LIMIT - if (nOut > SQL_TRACE_SIZE_LIMIT) { - nOut = SQL_TRACE_SIZE_LIMIT; - while (nOut < pVar->n - && (pVar->z[nOut] & 0xc0) == - 0x80) { - nOut++; - } - } -#endif sqlXPrintf(&out, "'%.*q'", nOut, pVar->z); -#ifdef SQL_TRACE_SIZE_LIMIT - if (nOut < pVar->n) { - sqlXPrintf(&out, "/*+%d bytes*/", - pVar->n - nOut); - } -#endif } else if (pVar->flags & MEM_Zero) { sqlXPrintf(&out, "zeroblob(%d)", pVar->u.nZero); @@ -188,21 +165,11 @@ sqlVdbeExpandSql(Vdbe * p, /* The prepared statement being evaluated */ assert(pVar->flags & MEM_Blob); sqlStrAccumAppend(&out, "x'", 2); nOut = pVar->n; -#ifdef SQL_TRACE_SIZE_LIMIT - if (nOut > SQL_TRACE_SIZE_LIMIT) - nOut = SQL_TRACE_SIZE_LIMIT; -#endif for (i = 0; i < nOut; i++) { sqlXPrintf(&out, "%02x", pVar->z[i] & 0xff); } sqlStrAccumAppend(&out, "'", 1); -#ifdef SQL_TRACE_SIZE_LIMIT - if (nOut < pVar->n) { - sqlXPrintf(&out, "/*+%d bytes*/", - pVar->n - nOut); - } -#endif } } } @@ -211,4 +178,3 @@ sqlVdbeExpandSql(Vdbe * p, /* The prepared statement being evaluated */ return sqlStrAccumFinish(&out); } -#endif /* #ifndef SQL_OMIT_TRACE */ diff --git a/src/box/sql/where.c b/src/box/sql/where.c index edc2074f9701619d2d5456bc0897107d74a2277e..b1eca58fba8263655fb3f61f5696b8efd41db43b 100644 --- a/src/box/sql/where.c +++ b/src/box/sql/where.c @@ -4560,12 +4560,6 @@ sqlWhereBegin(Parse * pParse, /* The parser context */ VdbeComment((v, "%s", space->def->name)); assert(pTabItem->iCursor == pLevel->iTabCur); sqlVdbeChangeP5(v, bFordelete); -#ifdef SQL_ENABLE_COLUMN_USED_MASK - sqlVdbeAddOp4Dup8(v, OP_ColumnsUsed, - pTabItem->iCursor, 0, 0, - (const u8 *)&pTabItem->colUsed, - P4_INT64); -#endif } if (pLoop->wsFlags & WHERE_INDEXED) { struct index_def *idx_def = pLoop->index_def; @@ -4640,30 +4634,6 @@ sqlWhereBegin(Parse * pParse, /* The parser context */ sqlVdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ } VdbeComment((v, "%s", idx_def->name)); -#ifdef SQL_ENABLE_COLUMN_USED_MASK - { - u64 colUsed = 0; - int ii, jj; - for (ii = 0; ii < pIx->nColumn; ii++) { - jj = pIx->aiColumn[ii]; - if (jj < 0) - continue; - if (jj > 63) - jj = 63; - if ((pTabItem-> - colUsed & MASKBIT(jj)) == - 0) - continue; - colUsed |= - ((u64) 1) << (ii < - 63 ? ii : 63); - } - sqlVdbeAddOp4Dup8(v, OP_ColumnsUsed, - iIndexCur, 0, 0, - (u8 *) & colUsed, - P4_INT64); - } -#endif /* SQL_ENABLE_COLUMN_USED_MASK */ } } } @@ -4677,10 +4647,7 @@ sqlWhereBegin(Parse * pParse, /* The parser context */ */ notReady = ~(Bitmask) 0; for (ii = 0; ii < nTabList; ii++) { - int addrExplain; - int wsFlags; pLevel = &pWInfo->a[ii]; - wsFlags = pLevel->pWLoop->wsFlags; #ifndef SQL_OMIT_AUTOMATIC_INDEX if ((pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX) != 0) { constructAutomaticIndex(pParse, &pWInfo->sWC, @@ -4690,17 +4657,11 @@ sqlWhereBegin(Parse * pParse, /* The parser context */ goto whereBeginError; } #endif - addrExplain = - sqlWhereExplainOneScan(pParse, pTabList, pLevel, ii, + sqlWhereExplainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags); pLevel->addrBody = sqlVdbeCurrentAddr(v); notReady = sqlWhereCodeOneLoopStart(pWInfo, ii, notReady); pWInfo->iContinue = pLevel->addrCont; - if ((wsFlags & WHERE_MULTI_OR) == 0 - && (wctrlFlags & WHERE_OR_SUBCLAUSE) == 0) { - sqlWhereAddScanStatus(v, pTabList, pLevel, - addrExplain); - } } /* Done. */ diff --git a/src/box/sql/whereInt.h b/src/box/sql/whereInt.h index 47430aef17b93b9658ce723a2faf3bee0516d205..e39e00210d1e3178731dfc9501596c61bcd220d7 100644 --- a/src/box/sql/whereInt.h +++ b/src/box/sql/whereInt.h @@ -102,9 +102,6 @@ struct WhereLevel { } u; struct WhereLoop *pWLoop; /* The selected WhereLoop object */ Bitmask notReady; /* FROM entries not usable at this level */ -#ifdef SQL_ENABLE_STMT_SCANSTATUS - int addrVisit; /* Address at which row is visited */ -#endif }; /* @@ -458,15 +455,6 @@ int sqlWhereExplainOneScan(Parse * pParse, /* Parse context */ int iFrom, /* Value for "from" column of output */ u16 wctrlFlags /* Flags passed to sqlWhereBegin() */ ); -#ifdef SQL_ENABLE_STMT_SCANSTATUS -void sqlWhereAddScanStatus(Vdbe * v, /* Vdbe to add scanstatus entry to */ - SrcList * pSrclist, /* FROM clause pLvl reads data from */ - WhereLevel * pLvl, /* Level to add scanstatus() entry for */ - int addrExplain /* Address of OP_Explain (or 0) */ - ); -#else -#define sqlWhereAddScanStatus(a, b, c, d) ((void)d) -#endif Bitmask sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the WHERE clause */ int iLevel, /* Which level of pWInfo->a[] should be coded */ Bitmask notReady /* Which tables are currently available */ diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c index a453fe9790584978ec13e8d9d260278f49c6a5fe..7d5dd46b0014c092b92b8ea4c8df2eb9ff9c5e7f 100644 --- a/src/box/sql/wherecode.c +++ b/src/box/sql/wherecode.c @@ -158,7 +158,7 @@ explainIndexRange(StrAccum * pStr, WhereLoop * pLoop) /* * This function is a no-op unless currently processing an EXPLAIN QUERY PLAN - * command, or if either SQL_DEBUG or SQL_ENABLE_STMT_SCANSTATUS was + * command, or if SQL_DEBUG was * defined at compile-time. If it is not a no-op, a single OP_Explain opcode * is added to the output to describe the table scan strategy in pLevel. * @@ -174,7 +174,7 @@ sqlWhereExplainOneScan(Parse * pParse, /* Parse context */ u16 wctrlFlags) /* Flags passed to sqlWhereBegin() */ { int ret = 0; -#if !defined(SQL_DEBUG) && !defined(SQL_ENABLE_STMT_SCANSTATUS) +#if !defined(SQL_DEBUG) if (pParse->explain == 2) #endif { @@ -253,14 +253,14 @@ sqlWhereExplainOneScan(Parse * pParse, /* Parse context */ " USING INTEGER PRIMARY KEY (rowid%s?)", zRangeOp); } -#ifdef SQL_EXPLAIN_ESTIMATED_ROWS + if (pLoop->nOut >= 10) { sqlXPrintf(&str, " (~%llu rows)", sqlLogEstToInt(pLoop->nOut)); } else { sqlStrAccumAppend(&str, " (~1 row)", 9); } -#endif + zMsg = sqlStrAccumFinish(&str); ret = sqlVdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, @@ -269,34 +269,6 @@ sqlWhereExplainOneScan(Parse * pParse, /* Parse context */ return ret; } -#ifdef SQL_ENABLE_STMT_SCANSTATUS -/* - * Configure the VM passed as the first argument with an - * sql_stmt_scanstatus() entry corresponding to the scan used to - * implement level pLvl. Argument pSrclist is a pointer to the FROM - * clause that the scan reads data from. - * - * If argument addrExplain is not 0, it must be the address of an - * OP_Explain instruction that describes the same loop. - */ -void -sqlWhereAddScanStatus(Vdbe * v, /* Vdbe to add scanstatus entry to */ - SrcList * pSrclist, /* FROM clause pLvl reads data from */ - WhereLevel * pLvl, /* Level to add scanstatus() entry for */ - int addrExplain) /* Address of OP_Explain (or 0) */ -{ - const char *zObj = 0; - WhereLoop *pLoop = pLvl->pWLoop; - if (pLoop->pIndex != 0) { - zObj = pLoop->pIndex->zName; - } else { - zObj = pSrclist->a[pLvl->iFrom].zName; - } - sqlVdbeScanStatus(v, addrExplain, pLvl->addrBody, pLvl->addrVisit, - pLoop->nOut, zObj); -} -#endif - /* * Disable a term in the WHERE clause. Except, do not disable the term * if it controls a LEFT OUTER JOIN and it did not originate in the ON @@ -1247,9 +1219,7 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W } else { assert(pLevel->p5 == 0); } - } else -#ifndef SQL_OMIT_OR_OPTIMIZATION - if (pLoop->wsFlags & WHERE_MULTI_OR) { + } else if (pLoop->wsFlags & WHERE_MULTI_OR) { /* Case 5: Two or more separately indexed terms connected by OR * * Example: @@ -1415,16 +1385,12 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W || db->mallocFailed); if (pSubWInfo) { WhereLoop *pSubLoop; - int addrExplain = - sqlWhereExplainOneScan(pParse, - pOrTab, - &pSubWInfo->a[0], - iLevel, - pLevel->iFrom, - 0); - sqlWhereAddScanStatus(v, pOrTab, - &pSubWInfo->a[0], - addrExplain); + sqlWhereExplainOneScan(pParse, + pOrTab, + &pSubWInfo->a[0], + iLevel, + pLevel->iFrom, + 0); /* This is the sub-WHERE clause body. First skip over * duplicate rows from prior sub-WHERE clauses, and record the @@ -1552,7 +1518,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W if (!untestedTerms) disableTerm(pLevel, pTerm); } else -#endif /* SQL_OMIT_OR_OPTIMIZATION */ { /* Case 6: There is no usable index. We must do a complete @@ -1578,10 +1543,6 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about the W } } -#ifdef SQL_ENABLE_STMT_SCANSTATUS - pLevel->addrVisit = sqlVdbeCurrentAddr(v); -#endif - /* Insert code to test every subexpression that can be completely * computed using the current set of tables. */ diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c index 30017b080f11656fc8b31461690754e8fdeb92c6..d30a710bb0ba11496f067a96d75a3b6543097d0f 100644 --- a/src/box/sql/whereexpr.c +++ b/src/box/sql/whereexpr.c @@ -222,7 +222,6 @@ operatorMask(int op) return c; } -#ifndef SQL_OMIT_LIKE_OPTIMIZATION /** * Check to see if the given expression is a LIKE operator that * can be optimized using inequality constraints. @@ -341,7 +340,6 @@ like_optimization_is_valid(Parse *pParse, Expr *pExpr, Expr **ppPrefix, sqlValueFree(pVal); return rc; } -#endif /* SQL_OMIT_LIKE_OPTIMIZATION */ /* * If the pBase expression originated in the ON or USING clause of @@ -451,7 +449,6 @@ whereCombineDisjuncts(SrcList * pSrc, /* the FROM clause */ exprAnalyze(pSrc, pWC, idxNew); } -#if !defined(SQL_OMIT_OR_OPTIMIZATION) /* * Analyze a term that consists of two or more OR-connected * subterms. So in: @@ -822,7 +819,6 @@ exprAnalyzeOrTerm(SrcList * pSrc, /* the FROM clause */ } } } -#endif /* !SQL_OMIT_OR_OPTIMIZATION */ /* * We already know that pExpr is a binary operator where both operands are @@ -1092,7 +1088,7 @@ exprAnalyze(SrcList * pSrc, /* the FROM clause */ (operatorMask(pDup->op) + eExtraOp) & opMask; } } -#ifndef SQL_OMIT_BETWEEN_OPTIMIZATION + /* If a term is the BETWEEN operator, create two new virtual terms * that define the range that the BETWEEN implements. For example: * @@ -1133,9 +1129,7 @@ exprAnalyze(SrcList * pSrc, /* the FROM clause */ markTermAsChild(pWC, idxNew, idxTerm); } } -#endif /* SQL_OMIT_BETWEEN_OPTIMIZATION */ -#if !defined(SQL_OMIT_OR_OPTIMIZATION) /* Analyze a term that is composed of two or more subterms connected by * an OR operator. */ @@ -1144,9 +1138,7 @@ exprAnalyze(SrcList * pSrc, /* the FROM clause */ exprAnalyzeOrTerm(pSrc, pWC, idxTerm); pTerm = &pWC->a[idxTerm]; } -#endif /* SQL_OMIT_OR_OPTIMIZATION */ -#ifndef SQL_OMIT_LIKE_OPTIMIZATION /* * Add constraints to reduce the search space on a LIKE * operator. @@ -1240,7 +1232,6 @@ exprAnalyze(SrcList * pSrc, /* the FROM clause */ markTermAsChild(pWC, idxNew2, idxTerm); } } -#endif /* SQL_OMIT_LIKE_OPTIMIZATION */ /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create * new terms for each component comparison - "a = ?" and "b = ?". The diff --git a/test/sql-tap/collation.test.lua b/test/sql-tap/collation.test.lua index 0bf54576d2c4e999c209c38394f099057b79638f..79547361c9a212cc6cf12e0cccfd883964c5b65e 100755 --- a/test/sql-tap/collation.test.lua +++ b/test/sql-tap/collation.test.lua @@ -452,7 +452,7 @@ for _, data_collation in ipairs(data_collations) do test:do_execsql_test( extendex_prefix.."select_plan_contains_b-tree", string.format("explain query plan select b from t1 order by b %s;",data_collation[1]), - {0,0,0,"SCAN TABLE T1", + {0,0,0,"SCAN TABLE T1 (~1048576 rows)", 0,0,0,"USE TEMP B-TREE FOR ORDER BY"}) test:do_execsql_test( extendex_prefix.."select", @@ -465,7 +465,7 @@ for _, data_collation in ipairs(data_collations) do test:do_execsql_test( extendex_prefix.."select_from_index_plan_does_not_contain_b-tree", string.format("explain query plan select b from t1 order by b %s;",data_collation[1]), - {0,0,0,"SCAN TABLE T1 USING COVERING INDEX I"}) + {0,0,0,"SCAN TABLE T1 USING COVERING INDEX I (~1048576 rows)"}) test:do_execsql_test( extendex_prefix.."select_from_index", string.format("select b from t1 order by b %s;",data_collation[1]), @@ -494,7 +494,7 @@ local like_testcases = {0, {"Aab", "aaa"}} }, {"2.1.2", "EXPLAIN QUERY PLAN SELECT * FROM tx1 WHERE s1 LIKE 'A%';", - {0, {0, 0, 0, "SEARCH TABLE TX1 USING COVERING INDEX I1 (S1>? AND S1<?)"}}}, + {0, {0, 0, 0, "SEARCH TABLE TX1 USING COVERING INDEX I1 (S1>? AND S1<?) (~16384 rows)"}}}, {"2.2.0", "PRAGMA case_sensitive_like = true;", {0}}, diff --git a/test/sql-tap/eqp.test.lua b/test/sql-tap/eqp.test.lua index 2aa2d96757303c4d0dd4ab62fe550046e8b51553..b8c3c66076179fd32cd35759a3140498ada81d97 100755 --- a/test/sql-tap/eqp.test.lua +++ b/test/sql-tap/eqp.test.lua @@ -30,7 +30,7 @@ local testprefix = "eqp" -- test:do_execsql_test( - 1.1, + "1.1", [[ CREATE TABLE t1(idt1 INT primary key, a INT, b INT, ex TEXT); CREATE INDEX i1 ON t1(a); @@ -40,67 +40,67 @@ test:do_execsql_test( ]]) test:do_eqp_test( - 1.2, + "1.2", [[ SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2; ]], { -- <1.2> - {0, 0, 1, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?)"}, - {0, 0, 1, "SEARCH TABLE T1 USING COVERING INDEX I2 (B=?)"}, - {0, 1, 0, "SCAN TABLE T2"} + {0, 0, 1, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?) (~10 rows)"}, + {0, 0, 1, "SEARCH TABLE T1 USING COVERING INDEX I2 (B=?) (~10 rows)"}, + {0, 1, 0, "SCAN TABLE T2 (~1048576 rows)"} -- </1.2> }) test:do_eqp_test( - 1.3, + "1.3", [[ SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2; ]], { -- <1.3> - {0, 0, 0, "SCAN TABLE T2"}, - {0, 1, 1, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?)"}, - {0, 1, 1, "SEARCH TABLE T1 USING COVERING INDEX I2 (B=?)"} + {0, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, + {0, 1, 1, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?) (~10 rows)"}, + {0, 1, 1, "SEARCH TABLE T1 USING COVERING INDEX I2 (B=?) (~10 rows)"} -- </1.3> }) test:do_eqp_test( - 1.3, + "1.3", [[ SELECT a FROM t1 ORDER BY a ]], { -- <1.3> - {0, 0, 0, "SCAN TABLE T1 USING COVERING INDEX I1"} + {0, 0, 0, "SCAN TABLE T1 USING COVERING INDEX I1 (~1048576 rows)"} -- </1.3> }) test:do_eqp_test( - 1.4, + "1.4", [[ SELECT a FROM t1 ORDER BY +a ]], { -- <1.4> - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {0, 0, 0, "USE TEMP B-TREE FOR ORDER BY"} -- </1.4> }) test:do_eqp_test( - 1.5, + "1.5", [[ SELECT a FROM t1 WHERE a=4 ]], { -- <1.5> - {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?)"} + {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?) (~10 rows)"} -- </1.5> }) test:do_eqp_test( - 1.6, + "1.6", [[ SELECT DISTINCT count(*) FROM t3 GROUP BY a; ]], { -- <1.6> - {0, 0, 0, "SCAN TABLE T3"}, + {0, 0, 0, "SCAN TABLE T3 (~1048576 rows)"}, {0, 0, 0, "USE TEMP B-TREE FOR GROUP BY"}, {0, 0, 0, "USE TEMP B-TREE FOR DISTINCT"}, @@ -108,40 +108,40 @@ test:do_eqp_test( }) test:do_eqp_test( - 1.7, + "1.7", [[ SELECT * FROM t3 JOIN (SELECT 1) ]], { -- <1.7> - {0, 0, 1, "SCAN SUBQUERY 1"}, - {0, 1, 0, "SCAN TABLE T3"}, + {0, 0, 1, "SCAN SUBQUERY 1 (~1 row)"}, + {0, 1, 0, "SCAN TABLE T3 (~1048576 rows)"}, -- </1.7> }) test:do_eqp_test( - 1.8, + "1.8", [[ SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2) ]], { -- <1.8> {1, 0, 0, "COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)"}, - {0, 0, 1, "SCAN SUBQUERY 1"}, - {0, 1, 0, "SCAN TABLE T3"}, + {0, 0, 1, "SCAN SUBQUERY 1 (~1 row)"}, + {0, 1, 0, "SCAN TABLE T3 (~1048576 rows)"}, -- </1.8> }) test:do_eqp_test( - 1.9, + "1.9", [[ SELECT * FROM t3 JOIN (SELECT 1 EXCEPT SELECT a FROM t3 LIMIT 17) ]], { -- <1.9> - {3, 0, 0, "SCAN TABLE T3"}, + {3, 0, 0, "SCAN TABLE T3 (~1048576 rows)"}, {1, 0, 0, "COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (EXCEPT)"}, - {0, 0, 1,"SCAN SUBQUERY 1"}, - {0, 1, 0,"SCAN TABLE T3"}, + {0, 0, 1,"SCAN SUBQUERY 1 (~1 row)"}, + {0, 1, 0,"SCAN TABLE T3 (~1048576 rows)"}, -- </1.9> }) @@ -152,24 +152,24 @@ test:do_eqp_test( SELECT * FROM t3 JOIN (SELECT 1 INTERSECT SELECT a FROM t3 LIMIT 17) ]], { -- <1.10> - {3, 0, 0, "SCAN TABLE T3"}, + {3, 0, 0, "SCAN TABLE T3 (~1048576 rows)"}, {1, 0, 0, "COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (INTERSECT)"}, - {0, 0, 1, "SCAN SUBQUERY 1"}, - {0, 1, 0, "SCAN TABLE T3"}, + {0, 0, 1, "SCAN SUBQUERY 1 (~1 row)"}, + {0, 1, 0, "SCAN TABLE T3 (~1048576 rows)"}, -- </1.10> }) test:do_eqp_test( - 1.11, + "1.11", [[ SELECT * FROM t3 JOIN (SELECT 1 UNION ALL SELECT a FROM t3 LIMIT 17) ]], { -- <1.11> - {3, 0, 0, "SCAN TABLE T3"}, + {3, 0, 0, "SCAN TABLE T3 (~1048576 rows)"}, {1, 0, 0, "COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)"}, - {0, 0, 1, "SCAN SUBQUERY 1"}, - {0, 1, 0, "SCAN TABLE T3"}, + {0, 0, 1, "SCAN SUBQUERY 1 (~1 row)"}, + {0, 1, 0, "SCAN TABLE T3 (~1048576 rows)"}, -- </1.11> }) @@ -179,7 +179,7 @@ test:do_eqp_test( -- test:drop_all_tables() test:do_execsql_test( - 2.1, + "2.1", [[ CREATE TABLE t1(idt1 INT primary key, x INT, y INT, ex TEXT); @@ -188,13 +188,13 @@ test:do_execsql_test( ]]) test:do_eqp_test("2.2.1", "SELECT DISTINCT min(x), max(x) FROM t1 GROUP BY x ORDER BY 1", { - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {0, 0, 0, "USE TEMP B-TREE FOR GROUP BY"}, {0, 0, 0, "USE TEMP B-TREE FOR DISTINCT"}, {0, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, }) test:do_eqp_test("2.2.2", "SELECT DISTINCT min(x), max(x) FROM t2 GROUP BY x ORDER BY 1", { - {0, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, + {0, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, {0, 0, 0, "USE TEMP B-TREE FOR DISTINCT"}, {0, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, }) @@ -204,34 +204,34 @@ test:do_eqp_test("2.2.2", "SELECT DISTINCT min(x), max(x) FROM t2 GROUP BY x ORD -- {0, 0, 0, "USE TEMP B-TREE FOR DISTINCT"}, --}) test:do_eqp_test("2.2.4", "SELECT DISTINCT * FROM t1, t2", { - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, -- changed after reordering indexes -- actually it does not matter (in fact, it seems like pk should have been used in both cases) --{0, 1, 1, "SCAN TABLE T2 USING COVERING INDEX t2i1"}, - {0, 1, 1, "SCAN TABLE T2"}, + {0, 1, 1, "SCAN TABLE T2 (~1048576 rows)"}, --{0, 0, 0, "USE TEMP B-TREE FOR DISTINCT"}, }) test:do_eqp_test("2.2.5", "SELECT DISTINCT * FROM t1, t2 ORDER BY t1.x", { - {0, 0, 0, "SCAN TABLE T1"}, - {0, 1, 1, "SCAN TABLE T2"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, + {0, 1, 1, "SCAN TABLE T2 (~1048576 rows)"}, --{0, 0, 0, "USE TEMP B-TREE FOR DISTINCT"}, {0, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, }) test:do_eqp_test("2.2.6", "SELECT DISTINCT t2.x FROM t1, t2 ORDER BY t2.x", { - {0, 0, 1, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, - {0, 1, 0, "SCAN TABLE T1"}, + {0, 0, 1, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, + {0, 1, 0, "SCAN TABLE T1 (~1048576 rows)"}, }) test:do_eqp_test("2.3.1", "SELECT max(x) FROM t2", { - {0, 0, 0, "SEARCH TABLE T2 USING COVERING INDEX T2I1"}, + {0, 0, 0, "SEARCH TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, }) test:do_eqp_test("2.3.2", "SELECT min(x) FROM t2", { - {0, 0, 0, "SEARCH TABLE T2 USING COVERING INDEX T2I1"}, + {0, 0, 0, "SEARCH TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, }) test:do_eqp_test("2.3.3", "SELECT min(x), max(x) FROM t2", { - {0, 0, 0, "SCAN TABLE T2"}, + {0, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, }) test:do_eqp_test("2.4.1", "SELECT * FROM t1 WHERE idt1=?", { - {0, 0, 0, "SEARCH TABLE T1 USING PRIMARY KEY (IDT1=?)"}, + {0, 0, 0, "SEARCH TABLE T1 USING PRIMARY KEY (IDT1=?) (~1 row)"}, }) --------------------------------------------------------------------------- -- Test cases eqp-3.* - tests for select statements that use sub-selects. @@ -242,9 +242,9 @@ test:do_eqp_test( SELECT (SELECT x FROM t1 AS sub) FROM t1; ]], { -- <3.1.1> - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {0, 0, 0, "EXECUTE SCALAR SUBQUERY 1"}, - {1, 0, 0, "SCAN TABLE T1 AS SUB"}, + {1, 0, 0, "SCAN TABLE T1 AS SUB (~1048576 rows)"}, -- </3.1.1> }) @@ -255,9 +255,9 @@ test:do_eqp_test( SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub); ]], { -- <3.1.2> - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {0, 0, 0, "EXECUTE SCALAR SUBQUERY 1"}, - {1, 0, 0, "SCAN TABLE T1 AS SUB"}, + {1, 0, 0, "SCAN TABLE T1 AS SUB (~1048576 rows)"}, -- </3.1.2> }) @@ -268,9 +268,9 @@ test:do_eqp_test( SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y); ]], { -- <3.1.3> - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {0, 0, 0, "EXECUTE SCALAR SUBQUERY 1"}, - {1, 0, 0, "SCAN TABLE T1 AS SUB"}, + {1, 0, 0, "SCAN TABLE T1 AS SUB (~1048576 rows)"}, {1, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, -- </3.1.3> @@ -282,9 +282,9 @@ test:do_eqp_test( SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x); ]], { -- <3.1.4> - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {0, 0, 0, "EXECUTE SCALAR SUBQUERY 1"}, - {1, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, + {1, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, -- </3.1.4> }) @@ -292,9 +292,9 @@ test:do_eqp_test( test:do_eqp_test("3.2.1", [[ SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5 ]], { - {1, 0, 0, "SCAN TABLE T1"}, + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {1, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, - {0, 0, 0, "SCAN SUBQUERY 1"}, + {0, 0, 0, "SCAN SUBQUERY 1 (~1 row)"}, {0, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, }) test:do_eqp_test("3.2.2", [[ @@ -303,33 +303,33 @@ test:do_eqp_test("3.2.2", [[ (SELECT * FROM t2 ORDER BY x LIMIT 10) AS x2 ORDER BY x2.y LIMIT 5 ]], { - {1, 0, 0, "SCAN TABLE T1"}, + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {1, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, - {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, - {0, 0, 0, "SCAN SUBQUERY 1 AS X1"}, - {0, 1, 1, "SCAN SUBQUERY 2 AS X2"}, + {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, + {0, 0, 0, "SCAN SUBQUERY 1 AS X1 (~1 row)"}, + {0, 1, 1, "SCAN SUBQUERY 2 AS X2 (~1 row)"}, {0, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, }) test:do_eqp_test("3.3.1", [[ SELECT * FROM t1 WHERE y IN (SELECT y FROM t2) ]], { - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~983040 rows)"}, {0, 0, 0, "EXECUTE LIST SUBQUERY 1"}, - {1, 0, 0, "SCAN TABLE T2"}, + {1, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, }) test:do_eqp_test("3.3.2", [[ SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x) ]], { - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~983040 rows)"}, {0, 0, 0, "EXECUTE CORRELATED LIST SUBQUERY 1"}, - {1, 0, 0, "SCAN TABLE T2"}, + {1, 0, 0, "SCAN TABLE T2 (~983040 rows)"}, }) test:do_eqp_test("3.3.3", [[ SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x) ]], { - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~983040 rows)"}, {0, 0, 0, "EXECUTE CORRELATED SCALAR SUBQUERY 1"}, - {1, 0, 0, "SCAN TABLE T2"}, + {1, 0, 0, "SCAN TABLE T2 (~983040 rows)"}, }) --------------------------------------------------------------------------- -- Test cases eqp-4.* - tests for composite select statements. @@ -340,8 +340,8 @@ test:do_eqp_test( SELECT * FROM t1 UNION ALL SELECT * FROM t2 ]], { -- <4.1.1> - {1, 0, 0, "SCAN TABLE T1"}, - {2, 0, 0, "SCAN TABLE T2"}, + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, + {2, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)"}, -- </4.1.1> @@ -353,9 +353,9 @@ test:do_eqp_test( SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 2 ]], { -- <4.1.2> - {1, 0, 0, "SCAN TABLE T1"}, + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {1, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, - {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, + {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)"}, -- </4.1.2> @@ -367,9 +367,9 @@ test:do_eqp_test( SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 2 ]], { -- <4.1.3> - {1, 0, 0, "SCAN TABLE T1"}, + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {1, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, - {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, + {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, {2, 0, 0, "USE TEMP B-TREE FOR RIGHT PART OF ORDER BY"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 2 (UNION)"}, @@ -382,9 +382,9 @@ test:do_eqp_test( SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 2 ]], { -- <4.1.4> - {1, 0, 0, "SCAN TABLE T1"}, + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {1, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, - {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, + {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, {2, 0, 0, "USE TEMP B-TREE FOR RIGHT PART OF ORDER BY"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)"}, @@ -397,9 +397,9 @@ test:do_eqp_test( SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 2 ]], { -- <4.1.5> - {1, 0, 0, "SCAN TABLE T1"}, + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {1, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, - {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, + {2, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, {2, 0, 0, "USE TEMP B-TREE FOR RIGHT PART OF ORDER BY"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)"} -- </4.1.5> @@ -470,8 +470,8 @@ test:do_eqp_test( SELECT x FROM t1 UNION SELECT x FROM t2 ]], { -- <4.3.1> - {1, 0, 0, "SCAN TABLE T1"}, - {2, 0, 0, "SCAN TABLE T2"}, + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, + {2, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)"}, -- </4.3.1> @@ -483,10 +483,10 @@ test:do_eqp_test( SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 ]], { -- <4.3.2> - {2, 0, 0, "SCAN TABLE T1"}, - {3, 0, 0, "SCAN TABLE T2"}, + {2, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, + {3, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, {1, 0, 0, "COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)"}, - {4, 0, 0, "SCAN TABLE T1"}, + {4, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)"} -- </4.3.2> }) @@ -497,11 +497,11 @@ test:do_eqp_test( SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 ORDER BY 1 ]], { -- <4.3.3> - {2, 0, 0, "SCAN TABLE T1"}, + {2, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {2, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, - {3, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1"}, + {3, 0, 0, "SCAN TABLE T2 USING COVERING INDEX T2I1 (~1048576 rows)"}, {1, 0, 0, "COMPOUND SUBQUERIES 2 AND 3 (UNION)"}, - {4, 0, 0, "SCAN TABLE T1"}, + {4, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, {4, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 4 (UNION)"} -- </4.3.3> @@ -523,7 +523,7 @@ test:do_execsql_test( ]]) test:do_eqp_test("5.1.1", "SELECT a, b FROM t1 WHERE a=1", { - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~524288 rows)"}, }) -- EVIDENCE-OF: R-55852-17599 sql> CREATE INDEX i1 ON t1(a); -- sql> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; @@ -536,7 +536,7 @@ test:do_execsql_test( ]]) test:do_eqp_test("5.2.1", "SELECT a, b FROM t1 WHERE a=1", { - {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?)"}, + {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?) (~10 rows)"}, }) -- EVIDENCE-OF: R-21179-11011 sql> CREATE INDEX i2 ON t1(a, b); -- sql> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; @@ -551,7 +551,7 @@ test:do_execsql_test( test:do_eqp_test("5.3.1", "SELECT a, b FROM t1 WHERE a=1", { -- It is equal for tarantol wheather to use i1 or i2 -- because both of them are covering - {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?)"}, + {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?) (~10 rows)"}, --{0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?)"}, }) -- EVIDENCE-OF: R-09991-48941 sql> EXPLAIN QUERY PLAN @@ -566,8 +566,8 @@ test:do_execsql_test( ]]) test:do_eqp_test("5.4.1", "SELECT t1.a, t2.c FROM t1, t2 WHERE t1.a=1 AND t1.b>2", { - {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I2 (A=? AND B>?)"}, - {0, 1, 1, "SCAN TABLE T2"}, + {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I2 (A=? AND B>?) (~2 rows)"}, + {0, 1, 1, "SCAN TABLE T2 (~1048576 rows)"}, }) -- EVIDENCE-OF: R-33626-61085 sql> EXPLAIN QUERY PLAN -- SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2; @@ -575,8 +575,8 @@ test:do_eqp_test("5.4.1", "SELECT t1.a, t2.c FROM t1, t2 WHERE t1.a=1 AND t1.b>2 -- 0|1|0|SCAN TABLE T2 -- test:do_eqp_test(5.5, "SELECT t1.a, t2.c FROM t2, t1 WHERE t1.a=1 AND t1.b>2", { - {0, 0, 1, "SEARCH TABLE T1 USING COVERING INDEX I2 (A=? AND B>?)"}, - {0, 1, 0, "SCAN TABLE T2"}, + {0, 0, 1, "SEARCH TABLE T1 USING COVERING INDEX I2 (A=? AND B>?) (~2 rows)"}, + {0, 1, 0, "SCAN TABLE T2 (~1048576 rows)"}, }) -- EVIDENCE-OF: R-04002-25654 sql> CREATE INDEX i3 ON t1(b); -- sql> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2; @@ -593,8 +593,8 @@ test:do_eqp_test("5.6.1", "SELECT a, b FROM t1 WHERE a=1 OR b=2", { -- It is equal for tarantol wheather to use i1 or i2 -- because both of them are covering --{0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I2 (A=?)"}, - {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?)"}, - {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I3 (B=?)"}, + {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?) (~10 rows)"}, + {0, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I3 (B=?) (~10 rows)"}, }) -- EVIDENCE-OF: R-24577-38891 sql> EXPLAIN QUERY PLAN -- SELECT c, d FROM t2 ORDER BY c; @@ -602,7 +602,7 @@ test:do_eqp_test("5.6.1", "SELECT a, b FROM t1 WHERE a=1 OR b=2", { -- 0|0|0|USE TEMP B-TREE FOR ORDER BY -- test:do_eqp_test(5.7, "SELECT c, d FROM t2 ORDER BY c", { - {0, 0, 0, "SCAN TABLE T2"}, + {0, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, {0, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, }) -- EVIDENCE-OF: R-58157-12355 sql> CREATE INDEX i4 ON t2(c); @@ -616,7 +616,7 @@ test:do_execsql_test( ]]) test:do_eqp_test("5.8.1", "SELECT c, d FROM t2 ORDER BY c", { - {0, 0, 0, "SCAN TABLE T2 USING COVERING INDEX I4"}, + {0, 0, 0, "SCAN TABLE T2 USING COVERING INDEX I4 (~1048576 rows)"}, }) -- EVIDENCE-OF: R-13931-10421 sql> EXPLAIN QUERY PLAN SELECT -- (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2; @@ -626,17 +626,17 @@ test:do_eqp_test("5.8.1", "SELECT c, d FROM t2 ORDER BY c", { -- 0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2 -- 2|0|0|SEARCH TABLE T1 USING COVERING INDEX i3 (b=?) -- -test:do_eqp_test(5.9, [[ +test:do_eqp_test("5.9", [[ SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2 ]], { - {0, 0, 0, "SCAN TABLE T2"}, + {0, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, {0, 0, 0, "EXECUTE SCALAR SUBQUERY 1"}, -- It is equally for tarantol wheather to use i1 or i2 -- because both of them are covering --{1, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I2 (A=?)"}, - {1, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?)"}, + {1, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I1 (A=?) (~10 rows)"}, {0, 0, 0, "EXECUTE CORRELATED SCALAR SUBQUERY 2"}, - {2, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I3 (B=?)"}, + {2, 0, 0, "SEARCH TABLE T1 USING COVERING INDEX I3 (B=?) (~10 rows)"}, }) -- EVIDENCE-OF: R-50892-45943 sql> EXPLAIN QUERY PLAN -- SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x; @@ -644,11 +644,11 @@ test:do_eqp_test(5.9, [[ -- 0|0|0|SCAN SUBQUERY 1 -- 0|0|0|USE TEMP B-TREE FOR GROUP BY -- -test:do_eqp_test(5.10, [[ +test:do_eqp_test("5.10", [[ SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x ]], { - {1, 0, 0, "SCAN TABLE T1 USING COVERING INDEX I1"}, - {0, 0, 0, "SCAN SUBQUERY 1"}, + {1, 0, 0, "SCAN TABLE T1 USING COVERING INDEX I1 (~1048576 rows)"}, + {0, 0, 0, "SCAN SUBQUERY 1 (~1 row)"}, {0, 0, 0, "USE TEMP B-TREE FOR GROUP BY"}, }) -- EVIDENCE-OF: R-46219-33846 sql> EXPLAIN QUERY PLAN @@ -656,9 +656,9 @@ test:do_eqp_test(5.10, [[ -- 0|0|0|SEARCH TABLE T2 USING COVERING INDEX i4 (c=?) -- 0|1|1|SCAN TABLE T1 -- -test:do_eqp_test(5.11, "SELECT a, b FROM (SELECT * FROM t2 WHERE c=1), t1", { - {0, 0, 0, "SEARCH TABLE T2 USING COVERING INDEX I4 (C=?)"}, - {0, 1, 1, "SCAN TABLE T1"}, +test:do_eqp_test("5.11", "SELECT a, b FROM (SELECT * FROM t2 WHERE c=1), t1", { + {0, 0, 0, "SEARCH TABLE T2 USING COVERING INDEX I4 (C=?) (~10 rows)"}, + {0, 1, 1, "SCAN TABLE T1 (~1048576 rows)"}, }) -- EVIDENCE-OF: R-37879-39987 sql> EXPLAIN QUERY PLAN -- SELECT a FROM t1 UNION SELECT c FROM t2; @@ -666,9 +666,9 @@ test:do_eqp_test(5.11, "SELECT a, b FROM (SELECT * FROM t2 WHERE c=1), t1", { -- 2|0|0|SCAN TABLE T2 -- 0|0|0|COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION) -- -test:do_eqp_test(5.12, "SELECT a,b FROM t1 UNION SELECT c, 99 FROM t2", { - {1, 0, 0, "SCAN TABLE T1"}, - {2, 0, 0, "SCAN TABLE T2"}, +test:do_eqp_test("5.12", "SELECT a,b FROM t1 UNION SELECT c, 99 FROM t2", { + {1, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, + {2, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)"}, }) -- EVIDENCE-OF: R-44864-63011 sql> EXPLAIN QUERY PLAN @@ -677,9 +677,9 @@ test:do_eqp_test(5.12, "SELECT a,b FROM t1 UNION SELECT c, 99 FROM t2", { -- 2|0|0|SCAN TABLE T2 2|0|0|USE TEMP B-TREE FOR ORDER BY -- 0|0|0|COMPOUND SUBQUERIES 1 AND 2 (EXCEPT) -- -test:do_eqp_test(5.13, "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1", { - {1, 0, 0, "SCAN TABLE T1 USING COVERING INDEX I1"}, - {2, 0, 0, "SCAN TABLE T2"}, +test:do_eqp_test("5.13", "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1", { + {1, 0, 0, "SCAN TABLE T1 USING COVERING INDEX I1 (~1048576 rows)"}, + {2, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, {2, 0, 0, "USE TEMP B-TREE FOR ORDER BY"}, {0, 0, 0, "COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)"}, }) @@ -725,24 +725,24 @@ test:do_eqp_test(5.13, "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1", { -- test:drop_all_tables() test:do_execsql_test( - 7.0, + "7.0", [[ CREATE TABLE t1(idt1 INT primary key, a INT, b INT, ex VARCHAR(100)); CREATE TABLE t2(idt2 INT primary key, a INT, b INT, ex VARCHAR(100)); CREATE INDEX i1 ON t2(a); ]]) -test:do_eqp_test(7.1, "SELECT count(*) FROM t1", { +test:do_eqp_test("7.1", "SELECT count(*) FROM t1", { {0, 0, 0, "B+tree count T1"}, }) -test:do_eqp_test(7.2, "SELECT count(*) FROM t2", { +test:do_eqp_test("7.2", "SELECT count(*) FROM t2", { {0, 0, 0, "B+tree count T2"}, }) -- MUST_WORK_TEST if (0 > 0) then test:do_execsql_test( - 7.3, + "7.3", [[ INSERT INTO t1(a,b) VALUES(1, 2); INSERT INTO t1(a,b) VALUES(3, 4); @@ -756,10 +756,10 @@ if (0 > 0) --db("close") --sql("db", "test.db") - test:do_eqp_test(7.4, "SELECT count(*) FROM t1", { + test:do_eqp_test("7.4", "SELECT count(*) FROM t1", { {0, 0, 0, "SCAN TABLE T1"} }) - test:do_eqp_test(7.5, "SELECT count(*) FROM t2", { + test:do_eqp_test("7.5", "SELECT count(*) FROM t2", { {0, 0, 0, "SCAN TABLE T2 USING COVERING INDEX I1"} }) --------------------------------------------------------------------------- @@ -768,14 +768,14 @@ if (0 > 0) end test:drop_all_tables() test:do_execsql_test( - 8.0, + "8.0", [[ CREATE TABLE t1(a INT , b INT , c INT , PRIMARY KEY(b, c)); CREATE TABLE t2(id INT primary key, a INT , b INT , c INT ); ]]) test:do_eqp_test("8.1.1", "SELECT * FROM t2", { - {0, 0, 0, "SCAN TABLE T2"}, + {0, 0, 0, "SCAN TABLE T2 (~1048576 rows)"}, }) -- test:do_eqp_test 8.1.2 "SELECT * FROM t2 WHERE rowid=?" { -- {0, 0, 0, "SEARCH TABLE T2 USING INTEGER PRIMARY KEY (rowid=?)"}, @@ -784,13 +784,13 @@ test:do_eqp_test("8.1.3", "SELECT count(*) FROM t2", { {0, 0, 0, "B+tree count T2"}, }) test:do_eqp_test("8.2.1", "SELECT * FROM t1", { - {0, 0, 0, "SCAN TABLE T1"}, + {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"}, }) test:do_eqp_test("8.2.2", "SELECT * FROM t1 WHERE b=?", { - {0, 0, 0, "SEARCH TABLE T1 USING PRIMARY KEY (B=?)"}, + {0, 0, 0, "SEARCH TABLE T1 USING PRIMARY KEY (B=?) (~10 rows)"}, }) test:do_eqp_test("8.2.3", "SELECT * FROM t1 WHERE b=? AND c=?", { - {0, 0, 0, "SEARCH TABLE T1 USING PRIMARY KEY (B=? AND C=?)"}, + {0, 0, 0, "SEARCH TABLE T1 USING PRIMARY KEY (B=? AND C=?) (~1 row)"}, }) test:do_eqp_test("8.2.4", "SELECT count(*) FROM t1", { {0, 0, 0, "B+tree count T1"}, diff --git a/test/sql-tap/gh-2996-indexed-by.test.lua b/test/sql-tap/gh-2996-indexed-by.test.lua index 1039ac15c28ad619d424af1b29fbdceb1720405c..4c5a4d053a082ce76a09a54ac517ad0bb603525a 100755 --- a/test/sql-tap/gh-2996-indexed-by.test.lua +++ b/test/sql-tap/gh-2996-indexed-by.test.lua @@ -37,7 +37,7 @@ test:do_eqp_test( "indexed-by-1.1", "SELECT b FROM t1 WHERE b <= 5", { -- <indexed-by-1.1> - { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX2 (B<?)' } + { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX2 (B<?) (~262144 rows)' } -- <indexed-by-1.1> }) @@ -45,7 +45,7 @@ test:do_eqp_test( "indexed-by-1.2", "SELECT b FROM t1 INDEXED BY t1ix1 WHERE b <= 5", { -- <indexed-by-1.2> - { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX1 (B<?)' } + { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX1 (B<?) (~262144 rows)' } -- <indexed-by-1.2> }) @@ -82,7 +82,7 @@ test:do_eqp_test( "indexed-by-1.5", "DELETE FROM t1 WHERE b <= 5", { -- <indexed-by-1.5> - { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX2 (B<?)' } + { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX2 (B<?) (~262144 rows)' } -- <indexed-by-1.5> }) @@ -90,7 +90,7 @@ test:do_eqp_test( "indexed-by-1.6", "DELETE FROM t1 INDEXED BY t1ix1 WHERE b <= 5", { -- <indexed-by-1.6> - { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX1 (B<?)' } + { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX1 (B<?) (~262144 rows)' } -- <indexed-by-1.6> }) @@ -124,7 +124,7 @@ test:do_eqp_test( "indexed-by-1.9", "UPDATE t1 SET b = 20 WHERE b = 10", { -- <indexed-by-1.9> - { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX2 (B=?)' } + { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX2 (B=?) (~10 rows)' } -- <indexed-by-1.9> }) @@ -132,7 +132,7 @@ test:do_eqp_test( "indexed-by-1.10", "UPDATE t1 INDEXED BY t1ix1 SET b = 20 WHERE b = 10", { -- <indexed-by-1.10> - { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX1 (B=?)' } + { 0, 0, 0, 'SEARCH TABLE T1 USING COVERING INDEX T1IX1 (B=?) (~10 rows)' } -- <indexed-by-1.10> }) diff --git a/test/sql-tap/index6.test.lua b/test/sql-tap/index6.test.lua index 416b800e1d7ebe4cdb331f94838a9e32c98f4572..15ae49245f70fb0212d06b3efc9815444cc9d74d 100755 --- a/test/sql-tap/index6.test.lua +++ b/test/sql-tap/index6.test.lua @@ -334,8 +334,8 @@ test:do_eqp_test( SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a) ]], { -- <index6-8.1> - {0, 0, 0, "SCAN TABLE T8A"}, - {0, 1, 1, "SEARCH TABLE T8B USING COVERING INDEX I8C (Y=?)"} + {0, 0, 0, "SCAN TABLE T8A (~1048576 rows)"}, + {0, 1, 1, "SEARCH TABLE T8B USING COVERING INDEX I8C (Y=?) (~9 rows)"} -- </index6-8.1> }) diff --git a/test/sql-tap/index7.test.lua b/test/sql-tap/index7.test.lua index 22072ec9397f6a2aa4ebec40678a118d1869c969..ed2b17c746309fc102ce073a883586dca95aa0cd 100755 --- a/test/sql-tap/index7.test.lua +++ b/test/sql-tap/index7.test.lua @@ -279,7 +279,7 @@ test:do_eqp_test( SELECT * FROM v4 WHERE d='xyz' AND c='def' ]], { -- <index7-6.4> - {0, 0, 0, "SEARCH TABLE T4 USING COVERING INDEX I4 (C=?)"} + {0, 0, 0, "SEARCH TABLE T4 USING COVERING INDEX I4 (C=?) (~9 rows)"} -- </index7-6.4> }) diff --git a/test/sql-tap/lua-tables.test.lua b/test/sql-tap/lua-tables.test.lua index 7ba1d7ac525823e45c6b3e134e06dca9ab7eeed4..07e0f6a1ecd32672daa6f74106da254ae150a7ba 100755 --- a/test/sql-tap/lua-tables.test.lua +++ b/test/sql-tap/lua-tables.test.lua @@ -149,7 +149,7 @@ test:do_eqp_test( [[ SELECT * FROM test WHERE id = 2; ]], { - {0, 0, 0, 'SEARCH TABLE TEST USING PRIMARY KEY (ID=?)'} + {0, 0, 0, 'SEARCH TABLE TEST USING PRIMARY KEY (ID=?) (~1 row)'} }) test:do_eqp_test( @@ -157,7 +157,7 @@ test:do_eqp_test( [[ SELECT * FROM test WHERE a = 5; ]], { - {0, 0, 0, 'SEARCH TABLE TEST USING COVERING INDEX secondary (A=?)'} + {0, 0, 0, 'SEARCH TABLE TEST USING COVERING INDEX secondary (A=?) (~1 row)'} }) -- Make sure that without format it is impossible to create diff --git a/test/sql-tap/tkt-385a5b56b9.test.lua b/test/sql-tap/tkt-385a5b56b9.test.lua index ffbb1a941e7aa34362ea3a8e5d8988adbe72f494..653d6822231e771cd2ebe515c232c9956e7956df 100755 --- a/test/sql-tap/tkt-385a5b56b9.test.lua +++ b/test/sql-tap/tkt-385a5b56b9.test.lua @@ -19,7 +19,7 @@ test:plan(9) -- ["source",[["testdir"],"\/tester.tcl"]] testprefix = "tkt-385a5b56b9" test:do_execsql_test( - 1.0, + "1.0", [[ CREATE TABLE t1(id INT primary key, x INT, y INT); INSERT INTO t1 VALUES(1, 1, NULL); @@ -28,7 +28,7 @@ test:do_execsql_test( ]]) test:do_execsql_test( - 1.1, + "1.1", [[ SELECT DISTINCT x, y FROM t1 ]], { @@ -38,13 +38,13 @@ test:do_execsql_test( }) test:do_execsql_test( - 1.2, + "1.2", [[ CREATE UNIQUE INDEX i1 ON t1(x, y) ]]) test:do_execsql_test( - 1.3, + "1.3", [[ SELECT DISTINCT x, y FROM t1 ]], { @@ -55,7 +55,7 @@ test:do_execsql_test( --------------------------------------------------------------------------- test:do_execsql_test( - 2.0, + "2.0", [[ CREATE TABLE t2(x INT primary key, y INT NOT NULL); CREATE UNIQUE INDEX t2x ON t2(x); @@ -63,41 +63,41 @@ test:do_execsql_test( ]]) test:do_eqp_test( - 2.1, + "2.1", " SELECT DISTINCT x FROM t2 ", { -- <2.1> - {0, 0, 0, "SCAN TABLE T2"} + {0, 0, 0, "SCAN TABLE T2 (~1048576 rows)"} -- </2.1> }) test:do_eqp_test( - 2.2, + "2.2", " SELECT DISTINCT y FROM t2 ", { -- <2.2> -- changed after reordering indexes -- actually it does not matter, because each y val is -- distinct even in pk --{0, 0, 0, "SCAN TABLE t2 USING COVERING INDEX t2y"} - {0, 0, 0, "SCAN TABLE T2"} + {0, 0, 0, "SCAN TABLE T2 (~1048576 rows)"} -- </2.2> }) test:do_eqp_test( - 2.3, + "2.3", " SELECT DISTINCT x, y FROM t2 WHERE y=10 ", { -- <2.3> - {0, 0, 0, "SEARCH TABLE T2 USING COVERING INDEX T2Y (Y=?)"} + {0, 0, 0, "SEARCH TABLE T2 USING COVERING INDEX T2Y (Y=?) (~1 row)"} -- </2.3> }) test:do_eqp_test( - 2.4, + "2.4", " SELECT DISTINCT x, y FROM t2 WHERE x=10 ", { -- <2.4> -- changed after reordering indexes + add pk to x affected -- actually it does not matter --{0, 0, 0, "SEARCH TABLE t2 USING INDEX t2x (x=?)"} - {0, 0, 0, "SEARCH TABLE T2 USING PRIMARY KEY (X=?)"} + {0, 0, 0, "SEARCH TABLE T2 USING PRIMARY KEY (X=?) (~1 row)"} -- </2.4> }) diff --git a/test/sql-tap/tkt-b75a9ca6b0.test.lua b/test/sql-tap/tkt-b75a9ca6b0.test.lua index ea684a73dbb1e433c31ac9ffcee340fb3119e2d7..89817d2afa998eab98c3dc75a75847a6513574da 100755 --- a/test/sql-tap/tkt-b75a9ca6b0.test.lua +++ b/test/sql-tap/tkt-b75a9ca6b0.test.lua @@ -39,8 +39,8 @@ test:do_execsql_test( CREATE INDEX i1 ON t1(x, y); ]]) -local idxscan = {0, 0, 0, "SCAN TABLE T1 USING COVERING INDEX I1"} -local tblscan = {0, 0, 0, "SCAN TABLE T1"} +local idxscan = {0, 0, 0, "SCAN TABLE T1 USING COVERING INDEX I1 (~1048576 rows)"} +local tblscan = {0, 0, 0, "SCAN TABLE T1 (~1048576 rows)"} local grpsort = {0, 0, 0, "USE TEMP B-TREE FOR GROUP BY"} local sort = {0, 0, 0, "USE TEMP B-TREE FOR ORDER BY"} local eqps = { diff --git a/test/sql-tap/tkt3442.test.lua b/test/sql-tap/tkt3442.test.lua index bdfdf8e176963e91349d00d1f3451153348f2c62..5b26122efeceabe5e58f9e0483595009670f5aaa 100755 --- a/test/sql-tap/tkt3442.test.lua +++ b/test/sql-tap/tkt3442.test.lua @@ -55,7 +55,7 @@ test:do_test( return EQP(" SELECT node FROM listhash WHERE id='5000' LIMIT 1; ") end, { -- <tkt3442-1.2> - 0, 0, 0, "SEARCH TABLE LISTHASH USING COVERING INDEX IDIDX (ID=?)" + 0, 0, 0, "SEARCH TABLE LISTHASH USING COVERING INDEX IDIDX (ID=?) (~1 row)" -- </tkt3442-1.2> }) @@ -65,7 +65,7 @@ test:do_test( return EQP([[ SELECT node FROM listhash WHERE id=5000 LIMIT 1; ]]) end, { -- <tkt3442-1.3> - 0, 0, 0, "SCAN TABLE LISTHASH" + 0, 0, 0, "SCAN TABLE LISTHASH (~262144 rows)" -- </tkt3442-1.3> }) diff --git a/test/sql-tap/where3.test.lua b/test/sql-tap/where3.test.lua index 86329d09681a8fedbc0add7504e350d3afff8761..ae9e37f614e2c7b8dab846f45de16cd5d19e637e 100755 --- a/test/sql-tap/where3.test.lua +++ b/test/sql-tap/where3.test.lua @@ -407,7 +407,7 @@ if 0 SELECT * FROM t400, t401, t402 WHERE t402.z LIKE 'abc%'; ]], { -- <where3-4.0> - 0, 0, 2, "SCAN TABLE T402", 0, 1, 0, "SCAN TABLE T400", 0, 2, 1, "SCAN TABLE T401" + 0, 0, 2, "SCAN TABLE T402 (~983040 rows)", 0, 1, 0, "SCAN TABLE T400 (~1048576 rows)", 0, 2, 1, "SCAN TABLE T401 (~1048576 rows)" -- </where3-4.0> }) @@ -418,7 +418,7 @@ if 0 SELECT * FROM t400, t401, t402 WHERE t401.r LIKE 'abc%'; ]], { -- <where3-4.1> - 0, 0, 1, "SCAN TABLE T401", 0, 1, 0, "SCAN TABLE T400", 0, 2, 2, "SCAN TABLE T402" + 0, 0, 1, "SCAN TABLE T401 (~983040 rows)", 0, 1, 0, "SCAN TABLE T400 (~1048576 rows)", 0, 2, 2, "SCAN TABLE T402 (~1048576 rows)" -- </where3-4.1> }) @@ -429,7 +429,7 @@ if 0 SELECT * FROM t400, t401, t402 WHERE t400.c LIKE 'abc%'; ]], { -- <where3-4.2> - 0, 0, 0, "SCAN TABLE T400", 0, 1, 1, "SCAN TABLE T401", 0, 2, 2, "SCAN TABLE T402" + 0, 0, 0, "SCAN TABLE T400 (~983040 rows)", 0, 1, 1, "SCAN TABLE T401 (~1048576 rows)", 0, 2, 2, "SCAN TABLE T402 (~1048576 rows)" -- </where3-4.2> }) diff --git a/test/sql-tap/whereG.test.lua b/test/sql-tap/whereG.test.lua index e9a39c5ce989c919f4ce3de3050b61970cd89947..177d9d14eaf554ecb6a6d71e081ad3bd5505f09a 100755 --- a/test/sql-tap/whereG.test.lua +++ b/test/sql-tap/whereG.test.lua @@ -278,7 +278,7 @@ test:do_execsql_test( -- -- reset_db test:do_execsql_test( - 5.1, + "5.1", [[ DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INT , b INT , c INT , PRIMARY KEY (a,b)); @@ -323,7 +323,7 @@ test:do_execsql_test( -- test:do_execsql_test( - 6.0, + "6.0", [[ DROP TABLE IF EXISTS t1; CREATE TABLE t1(i int PRIMARY KEY, x INT , y INT , z INT ); @@ -343,7 +343,7 @@ test:do_execsql_test( -- Crash discovered by AFL -- MUST_WORK_TEST test:do_execsql_test( - 7.0, + "7.0", [[ DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INT , b INT , PRIMARY KEY(a,b)); @@ -359,7 +359,7 @@ test:do_execsql_test( }) test:do_execsql_test( - 7.1, + "7.1", [[ SELECT unlikely(a), x FROM t1, t2 ORDER BY 1, 2; ]], { @@ -369,7 +369,7 @@ test:do_execsql_test( }) test:do_execsql_test( - 7.2, + "7.2", [[ SELECT likelihood(a,0.5), x FROM t1, t2 ORDER BY 1, 2; ]], { @@ -379,7 +379,7 @@ test:do_execsql_test( }) test:do_execsql_test( - 7.3, + "7.3", [[ SELECT coalesce(a,a), x FROM t1, t2 ORDER BY 1, 2; ]], { @@ -444,7 +444,7 @@ test:do_execsql_test( [[ EXPLAIN QUERY PLAN SELECT name FROM people WHERE height>=180; ]], - {0,0,0,"SCAN TABLE PEOPLE"}) + {0,0,0,"SCAN TABLE PEOPLE (~983040 rows)"}) test:do_execsql_test( "7.3", @@ -454,7 +454,7 @@ test:do_execsql_test( ]], -- {0,0,0,"SEARCH TABLE PEOPLE USING COVERING INDEX PEOPLE_IDX1" .. -- " (ANY(ROLE) AND HEIGHT>?)"} - {0,0,0,"SCAN TABLE PEOPLE" } + {0,0,0,"SCAN TABLE PEOPLE (~983040 rows)" } ) test:finish_test() diff --git a/test/sql/row-count.result b/test/sql/row-count.result index da9b70e79b3b17e16081fd68d766586f6964e141..e7841caa17900ab6cf9439586301fa92d154a510 100644 --- a/test/sql/row-count.result +++ b/test/sql/row-count.result @@ -303,7 +303,7 @@ box.execute("EXPLAIN QUERY PLAN INSERT INTO t1 VALUES ('b'), ('c'), ('d');") - name: detail type: TEXT rows: - - [0, 0, 0, 'SCAN TABLE T2'] + - [0, 0, 0, 'SCAN TABLE T2 (~262144 rows)'] ... box.execute("SELECT ROW_COUNT();") ---