diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 280c8b7ec2..dca70d0cbb 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -5833,14 +5833,43 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo return TSDB_CODE_SUCCESS; } +static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) { + bool tagProjection = false; + bool tableCounting = false; + + int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + + for (int32_t i = 0; i < numOfCols; ++i) { + SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functionId = pExpr->functionId; + + if (functionId == TSDB_FUNC_TAGPRJ) { + tagProjection = true; + continue; + } + + if (functionId == TSDB_FUNC_COUNT) { + assert(pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX); + tableCounting = true; + } + } + + return (tableCounting && tagProjection)? -1:0; +} + int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { const char* msg1 = "functions/columns not allowed in group by query"; const char* msg2 = "projection query on columns not allowed"; const char* msg3 = "group by not allowed on projection query"; const char* msg4 = "retrieve tags not compatible with group by or interval query"; + const char* msg5 = "functions can not be mixed up"; // only retrieve tags, group by is not supportted if (tscQueryTags(pQueryInfo)) { + if (doTagFunctionCheck(pQueryInfo) != TSDB_CODE_SUCCESS) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + } + if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); } else { diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 063b6af0e6..96fdde4fd6 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -188,8 +188,10 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSupporter* pSupporter1, SJ tsBufFlush(output2); tsBufDestroy(pSupporter1->pTSBuf); + pSupporter1->pTSBuf = NULL; tsBufDestroy(pSupporter2->pTSBuf); - + pSupporter2->pTSBuf = NULL; + TSKEY et = taosGetTimestampUs(); tscDebug("%p input1:%" PRId64 ", input2:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks " "intersecting, skey:%" PRId64 ", ekey:%" PRId64 ", numOfVnode:%d, elapsed time:%" PRId64 " us", @@ -219,12 +221,9 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { assert (pSupporter->uid != 0); taosGetTmpfilePath("join-", pSupporter->path); - pSupporter->f = fopen(pSupporter->path, "w"); - // todo handle error - if (pSupporter->f == NULL) { - tscError("%p failed to create tmp file:%s, reason:%s", pSql, pSupporter->path, strerror(errno)); - } + // do NOT create file here to reduce crash generated file left issue + pSupporter->f = NULL; return pSupporter; } @@ -244,12 +243,19 @@ static void tscDestroyJoinSupporter(SJoinSupporter* pSupporter) { tscFieldInfoClear(&pSupporter->fieldsInfo); + if (pSupporter->pTSBuf != NULL) { + tsBufDestroy(pSupporter->pTSBuf); + pSupporter->pTSBuf = NULL; + } + + unlink(pSupporter->path); + if (pSupporter->f != NULL) { fclose(pSupporter->f); - unlink(pSupporter->path); pSupporter->f = NULL; } + if (pSupporter->pVgroupTables != NULL) { taosArrayDestroy(pSupporter->pVgroupTables); pSupporter->pVgroupTables = NULL; @@ -526,6 +532,8 @@ static void quitAllSubquery(SSqlObj* pSqlObj, SJoinSupporter* pSupporter) { tscError("%p all subquery return and query failed, global code:%s", pSqlObj, tstrerror(pSqlObj->res.code)); freeJoinSubqueryObj(pSqlObj); } + + tscDestroyJoinSupporter(pSupporter); } // update the query time range according to the join results on timestamp @@ -921,6 +929,22 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow } if (numOfRows > 0) { // write the compressed timestamp to disk file + if(pSupporter->f == NULL) { + pSupporter->f = fopen(pSupporter->path, "w"); + + if (pSupporter->f == NULL) { + tscError("%p failed to create tmp file:%s, reason:%s", pSql, pSupporter->path, strerror(errno)); + + pParentSql->res.code = TAOS_SYSTEM_ERROR(errno); + + quitAllSubquery(pParentSql, pSupporter); + + tscAsyncResultOnError(pParentSql); + + return; + } + } + fwrite(pRes->data, (size_t)pRes->numOfRows, 1, pSupporter->f); fclose(pSupporter->f); pSupporter->f = NULL; @@ -930,6 +954,9 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows); pParentSql->res.code = TAOS_SYSTEM_ERROR(errno); + + quitAllSubquery(pParentSql, pSupporter); + tscAsyncResultOnError(pParentSql); return; diff --git a/src/connector/C#/TDengineDriver.cs b/src/connector/C#/TDengineDriver.cs index b6f143e181..205269501d 100644 --- a/src/connector/C#/TDengineDriver.cs +++ b/src/connector/C#/TDengineDriver.cs @@ -19,136 +19,137 @@ using System.Runtime.InteropServices; namespace TDengineDriver { - enum TDengineDataType { - TSDB_DATA_TYPE_NULL = 0, // 1 bytes - TSDB_DATA_TYPE_BOOL = 1, // 1 bytes - TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes - TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes - TSDB_DATA_TYPE_INT = 4, // 4 bytes - TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes - TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes - TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes - TSDB_DATA_TYPE_BINARY = 8, // string - TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes - TSDB_DATA_TYPE_NCHAR = 10 // unicode string - } - - enum TDengineInitOption - { - TSDB_OPTION_LOCALE = 0, - TSDB_OPTION_CHARSET = 1, - TSDB_OPTION_TIMEZONE = 2, - TDDB_OPTION_CONFIGDIR = 3, - TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 - } - - class TDengineMeta - { - public string name; - public short size; - public byte type; - public string TypeName() + enum TDengineDataType { - switch ((TDengineDataType)type) - { - case TDengineDataType.TSDB_DATA_TYPE_BOOL: - return "BOOLEAN"; - case TDengineDataType.TSDB_DATA_TYPE_TINYINT: - return "BYTE"; - case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: - return "SHORT"; - case TDengineDataType.TSDB_DATA_TYPE_INT: - return "INT"; - case TDengineDataType.TSDB_DATA_TYPE_BIGINT: - return "LONG"; - case TDengineDataType.TSDB_DATA_TYPE_FLOAT: - return "FLOAT"; - case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: - return "DOUBLE"; - case TDengineDataType.TSDB_DATA_TYPE_BINARY: - return "STRING"; - case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: - return "TIMESTAMP"; - case TDengineDataType.TSDB_DATA_TYPE_NCHAR: - return "NCHAR"; - default: - return "undefine"; - } - } - } - - class TDengine - { - public const int TSDB_CODE_SUCCESS = 0; - - [DllImport("taos.dll", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)] - static extern public void Init(); - - [DllImport("taos.dll", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)] - static extern public void Cleanup(); - - [DllImport("taos.dll", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)] - static extern public void Options(int option, string value); - - [DllImport("taos.dll", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr Connect(string ip, string user, string password, string db, short port); - - [DllImport("taos.dll", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)] - static extern private IntPtr taos_errstr(IntPtr res); - static public string Error(IntPtr res) - { - IntPtr errPtr = taos_errstr(res); - return Marshal.PtrToStringAnsi(errPtr); + TSDB_DATA_TYPE_NULL = 0, // 1 bytes + TSDB_DATA_TYPE_BOOL = 1, // 1 bytes + TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes + TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes + TSDB_DATA_TYPE_INT = 4, // 4 bytes + TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes + TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes + TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes + TSDB_DATA_TYPE_BINARY = 8, // string + TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes + TSDB_DATA_TYPE_NCHAR = 10 // unicode string } - [DllImport("taos.dll", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)] - static extern public int ErrorNo(IntPtr res); - - [DllImport("taos.dll", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr Query(IntPtr conn, string sqlstr); - - [DllImport("taos.dll", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)] - static extern public int AffectRows(IntPtr res); - - [DllImport("taos.dll", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)] - static extern public int FieldCount(IntPtr res); - - [DllImport("taos.dll", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)] - static extern private IntPtr taos_fetch_fields(IntPtr res); - static public List FetchFields(IntPtr res) + enum TDengineInitOption { - const int fieldSize = 68; - - List metas = new List(); - if (res == IntPtr.Zero) - { - return metas; - } - - int fieldCount = FieldCount(res); - IntPtr fieldsPtr = taos_fetch_fields(res); - - for (int i = 0; i < fieldCount; ++i) - { - int offset = i * fieldSize; - - TDengineMeta meta = new TDengineMeta(); - meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset); - meta.type = Marshal.ReadByte(fieldsPtr + offset + 65); - meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66); - metas.Add(meta); - } - - return metas; + TSDB_OPTION_LOCALE = 0, + TSDB_OPTION_CHARSET = 1, + TSDB_OPTION_TIMEZONE = 2, + TDDB_OPTION_CONFIGDIR = 3, + TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 } - [DllImport("taos.dll", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr FetchRows(IntPtr res); + class TDengineMeta + { + public string name; + public short size; + public byte type; + public string TypeName() + { + switch ((TDengineDataType)type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + return "BOOLEAN"; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + return "BYTE"; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + return "SHORT"; + case TDengineDataType.TSDB_DATA_TYPE_INT: + return "INT"; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + return "LONG"; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + return "FLOAT"; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + return "DOUBLE"; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + return "STRING"; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + return "TIMESTAMP"; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + return "NCHAR"; + default: + return "undefine"; + } + } + } - [DllImport("taos.dll", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr FreeResult(IntPtr res); + class TDengine + { + public const int TSDB_CODE_SUCCESS = 0; - [DllImport("taos.dll", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)] - static extern public int Close(IntPtr taos); - } -} \ No newline at end of file + [DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)] + static extern public void Init(); + + [DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)] + static extern public void Cleanup(); + + [DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)] + static extern public void Options(int option, string value); + + [DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr Connect(string ip, string user, string password, string db, short port); + + [DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr taos_errstr(IntPtr res); + static public string Error(IntPtr res) + { + IntPtr errPtr = taos_errstr(res); + return Marshal.PtrToStringAnsi(errPtr); + } + + [DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)] + static extern public int ErrorNo(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr Query(IntPtr conn, string sqlstr); + + [DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)] + static extern public int AffectRows(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)] + static extern public int FieldCount(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr taos_fetch_fields(IntPtr res); + static public List FetchFields(IntPtr res) + { + const int fieldSize = 68; + + List metas = new List(); + if (res == IntPtr.Zero) + { + return metas; + } + + int fieldCount = FieldCount(res); + IntPtr fieldsPtr = taos_fetch_fields(res); + + for (int i = 0; i < fieldCount; ++i) + { + int offset = i * fieldSize; + + TDengineMeta meta = new TDengineMeta(); + meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset); + meta.type = Marshal.ReadByte(fieldsPtr + offset + 65); + meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66); + metas.Add(meta); + } + + return metas; + } + + [DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FetchRows(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FreeResult(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)] + static extern public int Close(IntPtr taos); + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/DatabaseMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/DatabaseMetaDataTest.java index 284af3dfe7..19dabe0746 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/DatabaseMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/DatabaseMetaDataTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import java.sql.*; import java.util.Properties; -public class DatabaseMetaDataTest extends BaseTest { +public class DatabaseMetaDataTest { static Connection connection = null; static PreparedStatement statement = null; static String dbName = "test"; @@ -23,20 +23,21 @@ public class DatabaseMetaDataTest extends BaseTest { } Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata"); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties); String sql = "drop database if exists " + dbName; - statement = (TSDBPreparedStatement) connection.prepareStatement(sql); + statement = connection.prepareStatement(sql); statement.executeUpdate("create database if not exists " + dbName); statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); } @Test public void testMetaDataTest() throws SQLException { - DatabaseMetaData databaseMetaData = connection.getMetaData(); ResultSet resultSet = databaseMetaData.getTables(dbName, "t*", "t*", new String[]{"t"}); while (resultSet.next()) { @@ -180,7 +181,7 @@ public class DatabaseMetaDataTest extends BaseTest { databaseMetaData.getCatalogs(); // databaseMetaData.getTableTypes(); - databaseMetaData.getColumns("", "", "", ""); + databaseMetaData.getColumns(dbName, "", tName, ""); databaseMetaData.getColumnPrivileges("", "", "", ""); databaseMetaData.getTablePrivileges("", "", ""); databaseMetaData.getBestRowIdentifier("", "", "", 0, false); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java index 8de2e3b442..19bc5f713f 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java @@ -19,7 +19,7 @@ public class AppMemoryLeakTest { } } - @Test + @Test(expected = Exception.class) public void testCreateTooManyStatement() throws ClassNotFoundException, SQLException { Class.forName("com.taosdata.jdbc.TSDBDriver"); int stmtCnt = 0; @@ -30,15 +30,4 @@ public class AppMemoryLeakTest { } } - public static void main(String[] args) throws ClassNotFoundException, SQLException { - Class.forName("com.taosdata.jdbc.TSDBDriver"); - int stmtCnt = 0; - Connection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata"); - while (true) { - Statement stmt = conn.createStatement(); - System.out.println(++stmtCnt + " : " + stmt); - } - } - - } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectWrongDatabaseTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectWrongDatabaseTest.java new file mode 100644 index 0000000000..e4d2d7598d --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectWrongDatabaseTest.java @@ -0,0 +1,24 @@ +package com.taosdata.jdbc.cases; + +import org.junit.Assert; +import org.junit.Test; + +import java.sql.DriverManager; +import java.sql.SQLException; + +public class ConnectWrongDatabaseTest { + + @Test + public void connect() { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + DriverManager.getConnection("jdbc:TAOS://localhost:6030/wrong_db?user=root&password=taosdata"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (SQLException e) { + System.out.println(e.getMessage()); + Assert.assertEquals("TDengine Error: Invalid database name", e.getMessage()); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SqlSyntaxValidatorTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SqlSyntaxValidatorTest.java index fb570e16c4..ce84f967d0 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SqlSyntaxValidatorTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SqlSyntaxValidatorTest.java @@ -5,10 +5,6 @@ import org.junit.Test; public class SqlSyntaxValidatorTest { - @Test - public void validateSqlSyntax() { - } - @Test public void isSelectSQL() { Assert.assertTrue(SqlSyntaxValidator.isSelectSql("select * from test.weather")); diff --git a/src/query/inc/qTsbuf.h b/src/query/inc/qTsbuf.h index 90bd64336f..5d055782c9 100644 --- a/src/query/inc/qTsbuf.h +++ b/src/query/inc/qTsbuf.h @@ -88,6 +88,7 @@ typedef struct STSBuf { STSList tsData; // uncompressed raw ts data uint64_t numOfTotal; bool autoDelete; + bool remainOpen; int32_t tsOrder; // order of timestamp in ts comp buffer STSCursor cur; } STSBuf; diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 2997d56326..9fccb0d627 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -1268,12 +1268,14 @@ static void min_function_f(SQLFunctionCtx *pCtx, int32_t index) { } static void stddev_function(SQLFunctionCtx *pCtx) { - // the second stage to calculate standard deviation SStddevInfo *pStd = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - if (pStd->stage == 0) { // the first stage is to calculate average value + if (pStd->stage == 0) { + // the first stage is to calculate average value avg_function(pCtx); - } else { + } else if (pStd->num > 0) { + // the second stage to calculate standard deviation + // if pStd->num == 0, there are no numbers in the first round check. No need to do the second round double *retVal = &pStd->res; double avg = pStd->avg; @@ -3836,8 +3838,10 @@ static void ts_comp_finalize(SQLFunctionCtx *pCtx) { STSBuf * pTSbuf = pInfo->pTSBuf; tsBufFlush(pTSbuf); - strcpy(pCtx->aOutputBuf, pTSbuf->path); + *(FILE **)pCtx->aOutputBuf = pTSbuf->f; + + pTSbuf->remainOpen = true; tsBufDestroy(pTSbuf); doFinalizer(pCtx); } diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 9d96d31cec..7b544040bf 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -548,7 +548,7 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo *pWindowResInfo, int64_t t if (pWindowResInfo->curIndex == -1) { // the first window, from the previous stored value w.skey = pWindowResInfo->prevSKey; if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision); + w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; } else { w.ekey = w.skey + pQuery->interval.interval - 1; } @@ -2010,6 +2010,7 @@ static void doFreeQueryHandle(SQInfo* pQInfo) { assert(pMemRef->ref == 0 && pMemRef->imem == NULL && pMemRef->mem == NULL); } + static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { if (pRuntimeEnv->pQuery == NULL) { return; @@ -2021,6 +2022,16 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { qDebug("QInfo:%p teardown runtime env", pQInfo); cleanupResultRowInfo(&pRuntimeEnv->windowResInfo); + if (isTSCompQuery(pQuery)) { + FILE *f = *(FILE **)pQuery->sdata[0]->data; + + if (f) { + fclose(f); + *(FILE **)pQuery->sdata[0]->data = NULL; + } + } + + if (pRuntimeEnv->pCtx != NULL) { for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i]; @@ -6949,10 +6960,10 @@ static size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows) { * TODO handle the case that the file is too large to send back one time */ if (isTSCompQuery(pQuery) && (*numOfRows) > 0) { - struct stat fstat; - if (stat(pQuery->sdata[0]->data, &fstat) == 0) { - *numOfRows = fstat.st_size; - return fstat.st_size; + struct stat fStat; + if (fstat(fileno(*(FILE **)pQuery->sdata[0]->data), &fStat) == 0) { + *numOfRows = fStat.st_size; + return fStat.st_size; } else { qError("QInfo:%p failed to get file info, path:%s, reason:%s", pQInfo, pQuery->sdata[0]->data, strerror(errno)); return 0; @@ -6968,15 +6979,16 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { // load data from file to msg buffer if (isTSCompQuery(pQuery)) { - int32_t fd = open(pQuery->sdata[0]->data, O_RDONLY, 0666); + + FILE *f = *(FILE **)pQuery->sdata[0]->data; // make sure file exist - if (FD_VALID(fd)) { - uint64_t s = lseek(fd, 0, SEEK_END); + if (f) { + off_t s = lseek(fileno(f), 0, SEEK_END); - qDebug("QInfo:%p ts comp data return, file:%s, size:%"PRId64, pQInfo, pQuery->sdata[0]->data, s); - if (lseek(fd, 0, SEEK_SET) >= 0) { - size_t sz = read(fd, data, (uint32_t) s); + qDebug("QInfo:%p ts comp data return, file:%p, size:%"PRId64, pQInfo, f, s); + if (fseek(f, 0, SEEK_SET) >= 0) { + size_t sz = fread(data, 1, s, f); if(sz < s) { // todo handle error assert(0); } @@ -6984,15 +6996,8 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { UNUSED(s); } - close(fd); - unlink(pQuery->sdata[0]->data); - } else { - // todo return the error code to client and handle invalid fd - qError("QInfo:%p failed to open tmp file to send ts-comp data to client, path:%s, reason:%s", pQInfo, - pQuery->sdata[0]->data, strerror(errno)); - if (fd != -1) { - close(fd); - } + fclose(f); + *(FILE **)pQuery->sdata[0]->data = NULL; } // all data returned, set query over diff --git a/src/query/src/qTsbuf.c b/src/query/src/qTsbuf.c index d0c59fe5ef..a5d4690a8e 100644 --- a/src/query/src/qTsbuf.c +++ b/src/query/src/qTsbuf.c @@ -19,6 +19,8 @@ STSBuf* tsBufCreate(bool autoDelete, int32_t order) { if (pTSBuf == NULL) { return NULL; } + + pTSBuf->autoDelete = autoDelete; taosGetTmpfilePath("join", pTSBuf->path); pTSBuf->f = fopen(pTSBuf->path, "w+"); @@ -26,6 +28,10 @@ STSBuf* tsBufCreate(bool autoDelete, int32_t order) { free(pTSBuf); return NULL; } + + if (!autoDelete) { + unlink(pTSBuf->path); + } if (NULL == allocResForTSBuf(pTSBuf)) { return NULL; @@ -37,8 +43,7 @@ STSBuf* tsBufCreate(bool autoDelete, int32_t order) { tsBufResetPos(pTSBuf); pTSBuf->cur.order = TSDB_ORDER_ASC; - - pTSBuf->autoDelete = autoDelete; + pTSBuf->tsOrder = order; return pTSBuf; @@ -49,6 +54,8 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) { if (pTSBuf == NULL) { return NULL; } + + pTSBuf->autoDelete = autoDelete; tstrncpy(pTSBuf->path, path, sizeof(pTSBuf->path)); @@ -129,7 +136,6 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) { // ascending by default pTSBuf->cur.order = TSDB_ORDER_ASC; - pTSBuf->autoDelete = autoDelete; // tscDebug("create tsBuf from file:%s, fd:%d, size:%d, numOfGroups:%d, autoDelete:%d", pTSBuf->path, fileno(pTSBuf->f), // pTSBuf->fileSize, pTSBuf->numOfGroups, pTSBuf->autoDelete); @@ -147,8 +153,10 @@ void* tsBufDestroy(STSBuf* pTSBuf) { tfree(pTSBuf->pData); tfree(pTSBuf->block.payload); - - fclose(pTSBuf->f); + + if (!pTSBuf->remainOpen) { + fclose(pTSBuf->f); + } if (pTSBuf->autoDelete) { // ("tsBuf %p destroyed, delete tmp file:%s", pTSBuf, pTSBuf->path); diff --git a/src/util/src/hash.c b/src/util/src/hash.c index 1a9c6d314b..ede3e1e4ce 100644 --- a/src/util/src/hash.c +++ b/src/util/src/hash.c @@ -477,8 +477,6 @@ void taosHashEmpty(SHashObj *pHashObj) { return; } - uDebug("hash:%p cleanup hash table", pHashObj); - SHashNode *pNode, *pNext; __wr_lock(&pHashObj->lock, pHashObj->type); diff --git a/tests/examples/C#/taosdemo/README.md b/tests/examples/C#/taosdemo/README.md index 09e1d659b7..82a8dc674a 100644 --- a/tests/examples/C#/taosdemo/README.md +++ b/tests/examples/C#/taosdemo/README.md @@ -10,12 +10,14 @@ run C# version taosdemo === Usage: mono taosdemo.exe [OPTION...] + --help Show usage. + -h host, The host to connect to TDengine. Default is localhost. -p port, The TCP/IP port number to use for the connection. Default is 0. -u user, The user name to use when connecting to the server. Default is 'root'. -P password, The password to use when connecting to the server. Default is 'taosdata'. -d database, Destination database. Default is 'test'. - -a replica, Set the replica parameters of the database, Default 1, min: 1, max: 3. + -a replica, Set the replica parameters of the database, Default 1, min: 1, max: 5. -m table_prefix, Table prefix name. Default is 't'. -s sql file, The select sql file. -M stable, Use super table. @@ -26,8 +28,8 @@ Usage: mono taosdemo.exe [OPTION...] -l num_of_cols_per_record, The number of columns per record. Default is 3. -T num_of_threads, The number of threads. Default is 10. -r num_of_records_per_req, The number of records per request. Default is 1000. - -t num_of_tables, The number of tables. Default is 10000. - -n num_of_records_per_table, The number of records per table. Default is 10000. + -t num_of_tables, The number of tables. Default is 1. + -n num_of_records_per_table, The number of records per table. Default is 1. -c config_directory, Configuration directory. Default is '/etc/taos/'. -x flag, Insert only flag. -O order, Insert mode--0: In order, 1: Out of order. Default is in order. diff --git a/tests/examples/C#/taosdemo/TDengineDriver.cs b/tests/examples/C#/taosdemo/TDengineDriver.cs deleted file mode 120000 index 9bee9fb271..0000000000 --- a/tests/examples/C#/taosdemo/TDengineDriver.cs +++ /dev/null @@ -1 +0,0 @@ -../../../../src/connector/C#/TDengineDriver.cs \ No newline at end of file diff --git a/tests/examples/C#/taosdemo/TDengineDriver.cs b/tests/examples/C#/taosdemo/TDengineDriver.cs new file mode 100644 index 0000000000..205269501d --- /dev/null +++ b/tests/examples/C#/taosdemo/TDengineDriver.cs @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace TDengineDriver +{ + enum TDengineDataType + { + TSDB_DATA_TYPE_NULL = 0, // 1 bytes + TSDB_DATA_TYPE_BOOL = 1, // 1 bytes + TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes + TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes + TSDB_DATA_TYPE_INT = 4, // 4 bytes + TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes + TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes + TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes + TSDB_DATA_TYPE_BINARY = 8, // string + TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes + TSDB_DATA_TYPE_NCHAR = 10 // unicode string + } + + enum TDengineInitOption + { + TSDB_OPTION_LOCALE = 0, + TSDB_OPTION_CHARSET = 1, + TSDB_OPTION_TIMEZONE = 2, + TDDB_OPTION_CONFIGDIR = 3, + TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 + } + + class TDengineMeta + { + public string name; + public short size; + public byte type; + public string TypeName() + { + switch ((TDengineDataType)type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + return "BOOLEAN"; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + return "BYTE"; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + return "SHORT"; + case TDengineDataType.TSDB_DATA_TYPE_INT: + return "INT"; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + return "LONG"; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + return "FLOAT"; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + return "DOUBLE"; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + return "STRING"; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + return "TIMESTAMP"; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + return "NCHAR"; + default: + return "undefine"; + } + } + } + + class TDengine + { + public const int TSDB_CODE_SUCCESS = 0; + + [DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)] + static extern public void Init(); + + [DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)] + static extern public void Cleanup(); + + [DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)] + static extern public void Options(int option, string value); + + [DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr Connect(string ip, string user, string password, string db, short port); + + [DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr taos_errstr(IntPtr res); + static public string Error(IntPtr res) + { + IntPtr errPtr = taos_errstr(res); + return Marshal.PtrToStringAnsi(errPtr); + } + + [DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)] + static extern public int ErrorNo(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr Query(IntPtr conn, string sqlstr); + + [DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)] + static extern public int AffectRows(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)] + static extern public int FieldCount(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr taos_fetch_fields(IntPtr res); + static public List FetchFields(IntPtr res) + { + const int fieldSize = 68; + + List metas = new List(); + if (res == IntPtr.Zero) + { + return metas; + } + + int fieldCount = FieldCount(res); + IntPtr fieldsPtr = taos_fetch_fields(res); + + for (int i = 0; i < fieldCount; ++i) + { + int offset = i * fieldSize; + + TDengineMeta meta = new TDengineMeta(); + meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset); + meta.type = Marshal.ReadByte(fieldsPtr + offset + 65); + meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66); + metas.Add(meta); + } + + return metas; + } + + [DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FetchRows(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FreeResult(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)] + static extern public int Close(IntPtr taos); + } +} diff --git a/tests/examples/C#/taosdemo/taosdemo.cs b/tests/examples/C#/taosdemo/taosdemo.cs index 8e48fa2c8f..7e7c18db26 100644 --- a/tests/examples/C#/taosdemo/taosdemo.cs +++ b/tests/examples/C#/taosdemo/taosdemo.cs @@ -26,10 +26,10 @@ namespace TDengineDriver class TDengineTest { //connect parameters - private string host; - private string configDir; - private string user; - private string password; + private string host = "127.0.0.1"; + private string configDir = "C:/TDengine/cfg"; + private string user = "root"; + private string password = "taosdata"; private short port = 0; //sql parameters @@ -40,11 +40,12 @@ namespace TDengineDriver private bool isInsertOnly = false; private int queryMode = 1; - private long recordsPerTable = 10000; + private long recordsPerTable = 1; private int recordsPerRequest = 1; private int colsPerRecord = 3; private long batchRows = 1000; - private long numOfTables = 10000; + private long numOfTables = 1; + private short replica = 1; private IntPtr conn = IntPtr.Zero; // private long rowsInserted = 0; @@ -66,6 +67,8 @@ namespace TDengineDriver Console.WriteLine("Usage: mono taosdemo.exe [OPTION...]"); Console.WriteLine(""); string indent = " "; + Console.WriteLine("{0}{1}", indent, "--help Show usage."); + Console.WriteLine(""); Console.Write("{0}{1}", indent, "-h"); Console.Write("{0}{1}{2}\n", indent, indent, "host, The host to connect to TDengine. Default is localhost."); Console.Write("{0}{1}", indent, "-p"); @@ -77,7 +80,7 @@ namespace TDengineDriver Console.Write("{0}{1}", indent, "-d"); Console.Write("{0}{1}{2}\n", indent, indent, "database, Destination database. Default is 'test'."); Console.Write("{0}{1}", indent, "-a"); - Console.Write("{0}{1}{2}\n", indent, indent, "replica, Set the replica parameters of the database, Default 1, min: 1, max: 3."); + Console.Write("{0}{1}{2}\n", indent, indent, "replica, Set the replica parameters of the database, Default 1, min: 1, max: 5."); Console.Write("{0}{1}", indent, "-m"); Console.Write("{0}{1}{2}\n", indent, indent, "table_prefix, Table prefix name. Default is 't'."); Console.Write("{0}{1}", indent, "-s"); @@ -99,9 +102,9 @@ namespace TDengineDriver Console.Write("{0}{1}", indent, "-r"); Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_req, The number of records per request. Default is 1000."); Console.Write("{0}{1}", indent, "-t"); - Console.Write("{0}{1}{2}\n", indent, indent, "num_of_tables, The number of tables. Default is 10000."); + Console.Write("{0}{1}{2}\n", indent, indent, "num_of_tables, The number of tables. Default is 1."); Console.Write("{0}{1}", indent, "-n"); - Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_table, The number of records per table. Default is 10000."); + Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_table, The number of records per table. Default is 1."); Console.Write("{0}{1}", indent, "-c"); Console.Write("{0}{1}{2}\n", indent, indent, "config_directory, Configuration directory. Default is '/etc/taos/'."); Console.Write("{0}{1}", indent, "-x"); @@ -133,14 +136,15 @@ namespace TDengineDriver tablePrefix = this.GetArgumentAsString(argv, "-m", "t"); isInsertOnly = this.GetArgumentAsFlag(argv, "-x"); queryMode = (int)this.GetArgumentAsLong(argv, "-q", 0, 1, 0); - numOfTables = this.GetArgumentAsLong(argv, "-t", 1, 1000000000, 10000); + numOfTables = this.GetArgumentAsLong(argv, "-t", 1, 1000000000, 1); batchRows = this.GetArgumentAsLong(argv, "-r", 1, 10000, 1000); - recordsPerTable = this.GetArgumentAsLong(argv, "-n", 1, 100000000000, 10000); + recordsPerTable = this.GetArgumentAsLong(argv, "-n", 1, 100000000000, 1); recordsPerRequest = (int)this.GetArgumentAsLong(argv, "-r", 1, 10000, 1); colsPerRecord = (int)this.GetArgumentAsLong(argv, "-l", 1, 1024, 3); configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg"); useStable = this.GetArgumentAsFlag(argv, "-M"); + replica = (short)this.GetArgumentAsLong(argv, "-a", 1, 5, 1); methodOfDelete = (short)this.GetArgumentAsLong(argv, "-D", 0, 3, 0); numOfThreads = (short)this.GetArgumentAsLong(argv, "-T", 1, 10000, 1); order = this.GetArgumentAsFlag(argv, "-O"); @@ -153,13 +157,14 @@ namespace TDengineDriver Console.Write("# Server IP: {0}\n", host); Console.Write("# User: {0}\n", user); Console.Write("# Password: {0}\n", password); - Console.Write("# Use super table: {0}\n", useStable); Console.Write("# Number of Columns per record: {0}\n", colsPerRecord); Console.Write("# Number of Threads: {0}\n", numOfThreads); Console.Write("# Number of Tables: {0}\n", numOfTables); Console.Write("# Number of Data per Table: {0}\n", recordsPerTable); Console.Write("# Records/Request: {0}\n", recordsPerRequest); Console.Write("# Database name: {0}\n", dbName); + Console.Write("# Replica: {0}\n", replica); + Console.Write("# Use STable: {0}\n", useStable); Console.Write("# Table prefix: {0}\n", tablePrefix); Console.Write("# Data order: {0}\n", order); Console.Write("# Data out of order rate: {0}\n", rateOfOutorder); @@ -280,7 +285,7 @@ namespace TDengineDriver public void ConnectTDengine() { string db = ""; - DebugPrintFormat("host:{0} user:{1}, pass:{2}; db:{3}, port:{4}", + DebugPrintFormat("host:{0} user:{1}, pass:{2}; db:{3}, port:{4}\n", this.host, this.user, this.password, db, this.port); this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port); if (this.conn == IntPtr.Zero) @@ -320,6 +325,7 @@ namespace TDengineDriver createTableThread.verbose = verbose; createTableThread.dbName = this.dbName; createTableThread.tablePrefix = this.tablePrefix; + createTableThread.useStable = useStable; if (useStable) { createTableThread.stableName = stableName; @@ -363,7 +369,7 @@ namespace TDengineDriver public void CreateDb() { StringBuilder sql = new StringBuilder(); - sql.Append("CREATE DATABASE IF NOT EXISTS ").Append(this.dbName); + sql.Append("CREATE DATABASE IF NOT EXISTS ").Append(this.dbName).Append(" replica ").Append(this.replica); IntPtr res = TDengine.Query(this.conn, sql.ToString()); if (res != IntPtr.Zero) { @@ -429,7 +435,7 @@ namespace TDengineDriver insertThread.tablePrefix = this.tablePrefix; if (useStable) { - insertThread.stableName = stableName; + // insertThread.stableName = stableName; } insertThread.conn = conn; @@ -584,15 +590,20 @@ namespace TDengineDriver tester.InitTDengine(); tester.ConnectTDengine(); - tester.dropDatabase(); - tester.CreateDb(); - if (tester.useStable == true) + if (tester.isInsertOnly == false) { - tester.CreateStable(); - } + tester.dropDatabase(); + tester.CreateDb(); - tester.CreateTablesByThreads(); + + if (tester.useStable == true) + { + tester.CreateStable(); + } + + tester.CreateTablesByThreads(); + } Stopwatch watch = Stopwatch.StartNew(); tester.InsertByThreads(); @@ -619,7 +630,7 @@ namespace TDengineDriver public string dbName { set; get; } public IntPtr conn { set; get; } public string tablePrefix { set; get; } - public string stableName { set; get; } + // public string stableName { set; get; } public long recordsPerTable { set; get; } public long batchRows { set; get; } public long numOfTables { set; get; } @@ -643,9 +654,18 @@ namespace TDengineDriver public void ThreadMain() { - DebugPrintFormat("InsertDataThread {0} from {1} to {2}", id, start, end); + DebugPrintFormat("InsertDataThread {0} from {1} to {2}\n", id, start, end); StringBuilder sql = new StringBuilder(); - long beginTimestamp = 1551369600000L; + + DateTime now = DateTime.Now; + int h = now.Hour; + int m = now.Minute; + int s = now.Second; + + long baseTimestamp = 1609430400000; // 2021/01/01 0:0:0 + DebugPrintFormat("beginTime is {0} + {1}h:{2}m:{3}s\n", baseTimestamp, h, m, s); + long beginTimestamp = baseTimestamp + ((h*60 + m) * 60 + s) * 1000; + long rowsInserted = 0; // System.DateTime startTime = new System.DateTime(); @@ -660,7 +680,11 @@ namespace TDengineDriver sql.Append("INSERT INTO "). Append(this.dbName).Append(".").Append(this.tablePrefix).Append(table). Append(" VALUES"); - for (int batch = 0; batch < this.batchRows; ++batch) + if (recordsPerTable < batchRows) + { + batchRows = recordsPerTable; + } + for (int batch = 0; batch < batchRows; ++batch) { sql.Append("(") .Append(beginTimestamp + i + batch) @@ -701,6 +725,7 @@ namespace TDengineDriver public string tablePrefix { set; get; } public string stableName { set; get; } public bool verbose { set; get; } + public bool useStable { set; get; } private void DebugPrintFormat(string format, params object[] parameters) { @@ -720,7 +745,7 @@ namespace TDengineDriver public void ThreadMain() { - DebugPrintFormat("CreateTable {0} from {1} to {2}", id, start, end); + DebugPrintFormat("CreateTable {0} from {1} to {2}\n", id, start, end); StringBuilder sql = new StringBuilder(); @@ -728,9 +753,16 @@ namespace TDengineDriver { sql.Clear(); sql = sql.Append("CREATE TABLE IF NOT EXISTS "). - Append(this.dbName).Append(".").Append(this.tablePrefix).Append(tableId). - Append(" USING ").Append(this.dbName).Append(".").Append(this.stableName). - Append(" TAGS(").Append(tableId).Append(")"); + Append(this.dbName).Append(".").Append(this.tablePrefix).Append(tableId); + if (useStable == true) + { + sql = sql.Append(" USING ").Append(this.dbName).Append(".").Append(this.stableName). + Append(" TAGS(").Append(tableId).Append(")"); + } + else + { + sql = sql.Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10))"); + } IntPtr res = TDengine.Query(this.conn, sql.ToString()); if (res != IntPtr.Zero) { diff --git a/tests/examples/JDBC/JDBCDemo/pom.xml b/tests/examples/JDBC/JDBCDemo/pom.xml index 46729b8512..d075fc8f2a 100644 --- a/tests/examples/JDBC/JDBCDemo/pom.xml +++ b/tests/examples/JDBC/JDBCDemo/pom.xml @@ -48,4 +48,12 @@ + + + com.taosdata.jdbc + taos-jdbcdriver + 2.0.15 + + + diff --git a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JDBCDemo.java b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JDBCDemo.java index b5012c215f..e569de10cf 100644 --- a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JDBCDemo.java +++ b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JDBCDemo.java @@ -5,7 +5,7 @@ import java.util.Properties; public class JDBCDemo { private static String host; - private static String driverType; + private static String driverType = "jni"; private static final String dbName = "test"; private static final String tbName = "weather"; private Connection connection; @@ -21,7 +21,7 @@ public class JDBCDemo { } } - if (host == null || driverType == null) { + if (host == null) { printHelp(); } diff --git a/tests/script/general/parser/first_last_query.sim b/tests/script/general/parser/first_last_query.sim index 52d888b04d..9537b417f3 100644 --- a/tests/script/general/parser/first_last_query.sim +++ b/tests/script/general/parser/first_last_query.sim @@ -37,6 +37,7 @@ if $data02 != 0 then endi print data03 = $data03 if $data03 != 0.00000 then + print expect 0.00000, actual: $data03 return -1 endi if $data04 != 0.000000000 then diff --git a/tests/script/general/parser/function.sim b/tests/script/general/parser/function.sim index 78b63c2baf..a358ca7fce 100644 --- a/tests/script/general/parser/function.sim +++ b/tests/script/general/parser/function.sim @@ -361,3 +361,15 @@ endi if $data10 != @20-07-30 17:43:59.000@ then return -1 endi + +print =================>td-2610 +sql select stddev(k) from tm2 where ts='2020-12-29 18:46:19.109' +if $rows != 0 then + print expect 0, actual:$rows + return -1 +endi + +sql select twa(k) from tm2 where ts='2020-12-29 18:46:19.109' +if $rows != 0 then + return -1 +endi diff --git a/tests/script/general/parser/groupby.sim b/tests/script/general/parser/groupby.sim index 44bae6f242..606ad444d1 100644 --- a/tests/script/general/parser/groupby.sim +++ b/tests/script/general/parser/groupby.sim @@ -606,6 +606,10 @@ sql insert into t1 values ('2020-03-27 04:21:16.000', 1)('2020-03-27 04:31:17.00 sql insert into t2 values ('2020-03-27 04:11:16.000', 1)('2020-03-27 04:11:17.000', 2) ('2020-03-27 04:11:18.000', 3) ('2020-03-27 04:11:19.000', 4) ; sql insert into t2 values ('2020-03-27 04:21:16.000', 1)('2020-03-27 04:31:17.000', 2) ('2020-03-27 04:51:18.000', 3) ('2020-03-27 05:10:19.000', 4) ; +print =================>TD-2665 +sql_error create table txx as select avg(c) as t from st; +sql_error create table txx1 as select avg(c) as t from t1; + print =================>TD-2236 sql select first(ts),last(ts) from t1 group by c; if $rows != 4 then diff --git a/tests/script/general/parser/testSuite.sim b/tests/script/general/parser/testSuite.sim index a2cf305fae..cddd28817e 100644 --- a/tests/script/general/parser/testSuite.sim +++ b/tests/script/general/parser/testSuite.sim @@ -1,50 +1,50 @@ -run general/parser/alter.sim -sleep 500 -run general/parser/alter1.sim -sleep 500 -run general/parser/alter_stable.sim -sleep 500 -run general/parser/auto_create_tb.sim -sleep 500 -run general/parser/auto_create_tb_drop_tb.sim -sleep 500 -run general/parser/col_arithmetic_operation.sim -sleep 500 -run general/parser/columnValue.sim -sleep 500 -run general/parser/commit.sim -sleep 500 -run general/parser/create_db.sim -sleep 500 -run general/parser/create_mt.sim -sleep 500 -run general/parser/create_tb.sim -sleep 500 -run general/parser/dbtbnameValidate.sim -sleep 500 -run general/parser/fill.sim -sleep 500 -run general/parser/fill_stb.sim -sleep 500 -#run general/parser/fill_us.sim # -sleep 500 -run general/parser/first_last.sim -sleep 500 -run general/parser/import_commit1.sim -sleep 500 -run general/parser/import_commit2.sim -sleep 500 -run general/parser/import_commit3.sim -sleep 500 -#run general/parser/import_file.sim -sleep 500 -run general/parser/insert_tb.sim -sleep 500 -run general/parser/tags_dynamically_specifiy.sim -sleep 500 -run general/parser/interp.sim -sleep 500 -run general/parser/lastrow.sim +#run general/parser/alter.sim +#sleep 500 +#run general/parser/alter1.sim +#sleep 500 +#run general/parser/alter_stable.sim +#sleep 500 +#run general/parser/auto_create_tb.sim +#sleep 500 +#run general/parser/auto_create_tb_drop_tb.sim +#sleep 500 +#run general/parser/col_arithmetic_operation.sim +#sleep 500 +#run general/parser/columnValue.sim +#sleep 500 +#run general/parser/commit.sim +#sleep 500 +#run general/parser/create_db.sim +#sleep 500 +#run general/parser/create_mt.sim +#sleep 500 +#run general/parser/create_tb.sim +#sleep 500 +#run general/parser/dbtbnameValidate.sim +#sleep 500 +#run general/parser/fill.sim +#sleep 500 +#run general/parser/fill_stb.sim +#sleep 500 +##run general/parser/fill_us.sim # +#sleep 500 +#run general/parser/first_last.sim +#sleep 500 +#run general/parser/import_commit1.sim +#sleep 500 +#run general/parser/import_commit2.sim +#sleep 500 +#run general/parser/import_commit3.sim +#sleep 500 +##run general/parser/import_file.sim +#sleep 500 +#run general/parser/insert_tb.sim +#sleep 500 +#run general/parser/tags_dynamically_specifiy.sim +#sleep 500 +#run general/parser/interp.sim +#sleep 500 +#run general/parser/lastrow.sim sleep 500 run general/parser/limit.sim sleep 500