diff --git a/src/connector/python/linux/python2/taos/cursor.py b/src/connector/python/linux/python2/taos/cursor.py index 8c268d8afba2b971709fba6f157abfebdc8dfd1a..37c02d330e856717b5ed0bdac76723cf64d3860b 100644 --- a/src/connector/python/linux/python2/taos/cursor.py +++ b/src/connector/python/linux/python2/taos/cursor.py @@ -192,8 +192,10 @@ class TDengineCursor(object): buffer = [[] for i in range(len(self._fields))] self._rowcount = 0 while True: - block, num_of_fields = CTaosInterface.fetchBlock( - self._result, self._fields) + block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields) + errno = CTaosInterface.libtaos.taos_errno(self._result) + if errno != 0: + raise ProgrammingError(CTaosInterface.errStr(self._result), errno) if num_of_fields == 0: break self._rowcount += num_of_fields diff --git a/src/connector/python/linux/python3/taos/cursor.py b/src/connector/python/linux/python3/taos/cursor.py index 3f0f315d3388fcac1c752c847b7fa1c412b06749..ec7a85ee1a3f8cb0cd49aca8c2a4242dca89021e 100644 --- a/src/connector/python/linux/python3/taos/cursor.py +++ b/src/connector/python/linux/python3/taos/cursor.py @@ -207,8 +207,10 @@ class TDengineCursor(object): buffer = [[] for i in range(len(self._fields))] self._rowcount = 0 while True: - block, num_of_fields = CTaosInterface.fetchBlock( - self._result, self._fields) + block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields) + errno = CTaosInterface.libtaos.taos_errno(self._result) + if errno != 0: + raise ProgrammingError(CTaosInterface.errStr(self._result), errno) if num_of_fields == 0: break self._rowcount += num_of_fields diff --git a/src/connector/python/windows/python2/taos/cursor.py b/src/connector/python/windows/python2/taos/cursor.py index 7eee3bfc8f8559454f53aa967f5ad0294a1cb2bf..8714fe77cb739f23f79247a41d72aa127b6d6d25 100644 --- a/src/connector/python/windows/python2/taos/cursor.py +++ b/src/connector/python/windows/python2/taos/cursor.py @@ -142,6 +142,9 @@ class TDengineCursor(object): self._rowcount = 0 while True: block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields) + errno = CTaosInterface.libtaos.taos_errno(self._result) + if errno != 0: + raise ProgrammingError(CTaosInterface.errStr(self._result), errno) if num_of_fields == 0: break self._rowcount += num_of_fields for i in range(len(self._fields)): diff --git a/src/connector/python/windows/python3/taos/cursor.py b/src/connector/python/windows/python3/taos/cursor.py index 5f5aa4e1d7d9b454132f533a9e84cca2859db735..c2c442b06ee71ae90ec63662886c709e38d4d2ad 100644 --- a/src/connector/python/windows/python3/taos/cursor.py +++ b/src/connector/python/windows/python3/taos/cursor.py @@ -142,6 +142,9 @@ class TDengineCursor(object): self._rowcount = 0 while True: block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields) + errno = CTaosInterface.libtaos.taos_errno(self._result) + if errno != 0: + raise ProgrammingError(CTaosInterface.errStr(self._result), errno) if num_of_fields == 0: break self._rowcount += num_of_fields for i in range(len(self._fields)): diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index f742616b050887f1728d8ea3e7baf51bcdce9a95..869e2dd7ed1b4ce7f66294ff8f54f39dffa19fe7 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -7101,6 +7101,7 @@ void qCleanupQueryMgmt(void* pQMgmt) { void** qRegisterQInfo(void* pMgmt, uint64_t qInfo) { if (pMgmt == NULL) { + terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; return NULL; } @@ -7109,6 +7110,7 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qInfo) { SQueryMgmt *pQueryMgmt = pMgmt; if (pQueryMgmt->qinfoPool == NULL) { qError("QInfo:%p failed to add qhandle into qMgmt, since qMgmt is closed", (void *)qInfo); + terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; return NULL; } @@ -7116,6 +7118,7 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qInfo) { if (pQueryMgmt->closed) { // pthread_mutex_unlock(&pQueryMgmt->lock); qError("QInfo:%p failed to add qhandle into cache, since qMgmt is colsing", (void *)qInfo); + terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; return NULL; } else { TSDB_CACHE_PTR_TYPE handleVal = (TSDB_CACHE_PTR_TYPE) qInfo; diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index 2a39e2e76f3285f6836dcc8793e79f2d45269809..11e094fe983f9872cb0b4c52e8adbcc9ac54f475 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -191,10 +191,12 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) { if (code == TSDB_CODE_SUCCESS) { handle = qRegisterQInfo(pVnode->qMgmt, (uint64_t)pQInfo); if (handle == NULL) { // failed to register qhandle, todo add error test case + pRsp->code = terrno; + terrno = 0; vError("vgId:%d QInfo:%p register qhandle failed, return to app, code:%s", pVnode->vgId, (void *)pQInfo, tstrerror(pRsp->code)); - pRsp->code = TSDB_CODE_QRY_INVALID_QHANDLE; qDestroyQueryInfo(pQInfo); // destroy it directly + return pRsp->code; } else { assert(*handle == pQInfo); pRsp->qhandle = htobe64((uint64_t)pQInfo); diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index fd973b8b7604c9c6b7148a336ca1ac082cd1b548..4b27c42d3875fec5f645e73c3f081ec08329f607 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -149,6 +149,7 @@ python3 ./test.py -f query/queryNullValueTest.py python3 ./test.py -f query/queryInsertValue.py python3 ./test.py -f query/queryConnection.py python3 ./test.py -f query/natualInterval.py +python3 ./test.py -f query/bug1471.py #stream python3 ./test.py -f stream/metric_1.py diff --git a/tests/pytest/query/bug1471.py b/tests/pytest/query/bug1471.py new file mode 100644 index 0000000000000000000000000000000000000000..f1cb0bdcdfbb085410d0001606208e11373687a1 --- /dev/null +++ b/tests/pytest/query/bug1471.py @@ -0,0 +1,73 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +import time +import threading + + +class myThread(threading.Thread): + def __init__(self, conn): + threading.Thread.__init__(self) + self.event = threading.Event() + self.conn = taos.connect(conn._host, port=conn._port, config=conn._config) + + def run(self): + cur = self.conn.cursor() + self.event.wait() + cur.execute("drop database db") + cur.close() + self.conn.close() + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + def run(self): + for i in range(50): + print("round", i) + thread = myThread(tdSql.cursor._connection) + thread.start() + + tdSql.execute('reset query cache') + tdSql.execute('drop database if exists db') + tdSql.execute('create database db') + tdSql.execute('use db') + tdSql.execute("create table car (ts timestamp, s int)") + tdSql.execute("insert into car values('2020-10-19 17:00:00', 123)") + + thread.event.set() + try: + tdSql.query("select s from car where ts = '2020-10-19 17:00:00'") + except Exception as e: + pass + else: + tdSql.checkData(0, 0, 123) + + thread.join() + time.sleep(0.2) + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase())