未验证 提交 6370d36a 编写于 作者: C cpwu 提交者: GitHub

Merge branch 'taosdata:develop' into doc/TD-12532

......@@ -1084,8 +1084,9 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSql
uint64_t uid = tscExprGet(pQueryInfo, 0)->base.uid;
int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
STableMetaInfo* pTableMetaInfo = NULL;
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
if (pTableMetaInfo->pTableMeta->id.uid == uid) {
tableIndex = i;
break;
......@@ -1097,7 +1098,11 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSql
}
SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
if (pTableMetaInfo) {
tstrncpy(s.name, pTableMetaInfo->pTableMeta->schema[PRIMARYKEY_TIMESTAMP_COL_INDEX].name, sizeof(s.name));
} else {
tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
}
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL, 0);
......
......@@ -54,7 +54,7 @@ public abstract class TSDBConstants {
public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint
public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int
public static final int TSDB_DATA_TYPE_UBIGINT = 14; //unsigned bigint
public static final int TSDB_DATA_TYPE_JSON = 15; //json
// nchar column max length
public static final int maxFieldSize = 16 * 1024;
......@@ -129,6 +129,8 @@ public abstract class TSDBConstants {
return Types.TIMESTAMP;
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return Types.NCHAR;
case TSDBConstants.TSDB_DATA_TYPE_JSON:
return Types.OTHER;
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE, "unknown taos type: " + taosType + " in tdengine");
}
......@@ -160,6 +162,8 @@ public abstract class TSDBConstants {
return "TIMESTAMP";
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return "NCHAR";
case TSDBConstants.TSDB_DATA_TYPE_JSON:
return "JSON";
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE, "unknown taos type: " + taosType + " in tdengine");
}
......
......@@ -615,6 +615,18 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
}
}
public void setTagJson(int index, String value) {
ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_JSON));
String charset = TaosGlobalConfig.getCharset();
try {
this.tagValueLength += value.getBytes(charset).length;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage());
}
}
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
if (this.colData.size() == 0) {
this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null));
......@@ -774,6 +786,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
}
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
String charset = TaosGlobalConfig.getCharset();
String val = (String) tag.value;
......
......@@ -151,6 +151,7 @@ public class TSDBResultSetBlockData {
this.colData.set(col, lb);
break;
}
case TSDBConstants.TSDB_DATA_TYPE_JSON:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
buf.order(ByteOrder.LITTLE_ENDIAN);
......@@ -199,6 +200,7 @@ public class TSDBResultSetBlockData {
}
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
return Integer.parseInt((String) obj);
}
......@@ -232,6 +234,7 @@ public class TSDBResultSetBlockData {
}
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
if ("TRUE".compareToIgnoreCase((String) obj) == 0) {
return Boolean.TRUE;
......@@ -271,6 +274,7 @@ public class TSDBResultSetBlockData {
}
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
return Long.parseLong((String) obj);
}
......@@ -308,6 +312,7 @@ public class TSDBResultSetBlockData {
}
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
return Double.parseDouble((String) obj);
}
......@@ -406,6 +411,7 @@ public class TSDBResultSetBlockData {
return new String(dest);
}
case TSDBConstants.TSDB_DATA_TYPE_JSON:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
ByteBuffer bb = (ByteBuffer) this.colData.get(col);
bb.position((fieldSize + BINARY_LENGTH_OFFSET) * this.rowIndex);
......
......@@ -78,6 +78,7 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
return obj.toString().contains("1");
}
......@@ -147,6 +148,7 @@ public class TSDBResultSetRowData {
return ((Long) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
return Integer.parseInt((String) obj);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
return parseUnsignedTinyIntToInt(obj);
......@@ -228,6 +230,7 @@ public class TSDBResultSetRowData {
return (Long) obj;
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
return Long.parseLong((String) obj);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: {
byte value = (byte) obj;
......@@ -418,6 +421,7 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return new String((byte[]) obj);
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_JSON:
return (String) obj;
default:
return String.valueOf(obj);
......
package com.taosdata.jdbc.rs;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
......@@ -184,6 +186,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return row.getString(colIndex) == null ? null : row.getString(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_JSON:
// all json tag or just a json tag value
return row.get(colIndex) != null && (row.get(colIndex) instanceof String || row.get(colIndex) instanceof JSONObject)
? JSON.toJSONString(row.get(colIndex), SerializerFeature.WriteMapNullValue)
: row.get(colIndex);
default:
return row.get(colIndex);
}
......
......@@ -8,6 +8,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import java.sql.*;
import java.util.ArrayList;
import java.util.Random;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(CatalogRunner.class)
......@@ -197,6 +199,8 @@ public class JsonTagTest {
@Description("select json tag from stable")
public void case04_select03() throws SQLException {
ResultSet resultSet = statement.executeQuery("select jtag from jsons1");
ResultSetMetaData metaData = resultSet.getMetaData();
metaData.getColumnTypeName(1);
int count = 0;
while (resultSet.next()) {
count++;
......@@ -1176,6 +1180,110 @@ public class JsonTagTest {
close(resultSet);
}
@Test
@Description("query metadata for json")
public void case19_selectMetadata01() throws SQLException {
ResultSet resultSet = statement.executeQuery("select jtag from jsons1");
ResultSetMetaData metaData = resultSet.getMetaData();
int columnType = metaData.getColumnType(1);
String columnTypeName = metaData.getColumnTypeName(1);
Assert.assertEquals(Types.OTHER, columnType);
Assert.assertEquals("JSON", columnTypeName);
close(resultSet);
}
@Test
@Description("query metadata for json")
public void case19_selectMetadata02() throws SQLException {
ResultSet resultSet = statement.executeQuery("select *,jtag from jsons1");
ResultSetMetaData metaData = resultSet.getMetaData();
int columnType = metaData.getColumnType(6);
String columnTypeName = metaData.getColumnTypeName(6);
Assert.assertEquals(Types.OTHER, columnType);
Assert.assertEquals("JSON", columnTypeName);
close(resultSet);
}
@Test
@Description("query metadata for one json result")
public void case19_selectMetadata03() throws SQLException {
ResultSet resultSet = statement.executeQuery("select jtag->'tag1' from jsons1_6");
ResultSetMetaData metaData = resultSet.getMetaData();
int columnType = metaData.getColumnType(1);
String columnTypeName = metaData.getColumnTypeName(1);
Assert.assertEquals(Types.OTHER, columnType);
Assert.assertEquals("JSON", columnTypeName);
resultSet.next();
String string = resultSet.getString(1);
Assert.assertEquals("11", string);
close(resultSet);
}
@Test
@Description("stmt batch insert with json tag")
public void case20_batchInsert() throws SQLException {
String jsonTag = "{\"tag1\":\"fff\",\"tag2\":5,\"tag3\":true}";
statement.execute("drop table if exists jsons5");
statement.execute("CREATE STABLE IF NOT EXISTS jsons5 (ts timestamp, dataInt int, dataStr nchar(20)) TAGS(jtag json)");
String sql = "INSERT INTO ? USING jsons5 TAGS (?) VALUES ( ?,?,? )";
try (PreparedStatement pst = connection.prepareStatement(sql)) {
TSDBPreparedStatement ps = pst.unwrap(TSDBPreparedStatement.class);
// 设定数据表名:
ps.setTableName("batch_test");
// 设定 TAGS 取值 setTagNString or setTagJson:
// ps.setTagNString(0, jsonTag);
ps.setTagJson(0, jsonTag);
// VALUES 部分以逐列的方式进行设置:
int numOfRows = 4;
ArrayList<Long> ts = new ArrayList<>();
for (int i = 0; i < numOfRows; i++) {
ts.add(System.currentTimeMillis() + i);
}
ps.setTimestamp(0, ts);
Random r = new Random();
int random = 10 + r.nextInt(5);
ArrayList<Integer> c1 = new ArrayList<>();
for (int i = 0; i < numOfRows; i++) {
if (i % random == 0) {
c1.add(null);
} else {
c1.add(r.nextInt());
}
}
ps.setInt(1, c1);
ArrayList<String> c2 = new ArrayList<>();
for (int i = 0; i < numOfRows; i++) {
c2.add("分支" + i % 4);
}
ps.setNString(2, c2, 10);
// AddBatch 之后,缓存并未清空。为避免混乱,并不推荐在 ExecuteBatch 之前再次绑定新一批的数据:
ps.columnDataAddBatch();
// 执行绑定数据后的语句:
ps.columnDataExecuteBatch();
}
ResultSet resultSet = statement.executeQuery("select jtag from batch_test");
ResultSetMetaData metaData = resultSet.getMetaData();
String columnName = metaData.getColumnName(1);
Assert.assertEquals("jtag", columnName);
Assert.assertEquals("JSON", metaData.getColumnTypeName(1));
resultSet.next();
String string = resultSet.getString(1);
Assert.assertEquals(jsonTag, string);
resultSet.close();
resultSet = statement.executeQuery("select jtag->'tag2' from batch_test");
resultSet.next();
long l = resultSet.getLong(1);
Assert.assertEquals(5, l);
resultSet.close();
}
private void close(ResultSet resultSet) {
try {
if (null != resultSet) {
......
......@@ -120,7 +120,7 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData
bool exceedMax = false, exceedMin = false;
point1 = (SPoint){.key = *(TSKEY*)(prev), .val = prev + pCol->col.offset};
point2 = (SPoint){.key = ts, .val = srcData[i] + pFillInfo->index * bytes};
if (isNull(point2.val, type)) {
if (isNull(point1.val, type) || isNull(point2.val, type)) {
setNull(val1, pCol->col.type, bytes);
continue;
}
......
......@@ -288,6 +288,7 @@ python3 test.py -f query/nestedQuery/queryWithSpread.py
python3 ./test.py -f query/bug6586.py
# python3 ./test.py -f query/bug5903.py
python3 ./test.py -f query/queryLimit.py
python3 ./test.py -f query/queryPriKey.py
#stream
python3 ./test.py -f stream/metric_1.py
......
###################################################################
# 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
from util.log import *
from util.cases import *
from util.sql import *
from util.dnodes import *
class TDTestCase:
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
def run(self):
tdSql.prepare()
tdSql.execute("drop database if exists tdb")
tdSql.execute("create database if not exists tdb keep 3650")
tdSql.execute("use tdb")
tdSql.execute(
"create table stb1 (time timestamp, c1 int) TAGS (t1 int)"
)
tdSql.execute(
"insert into t1 using stb1 tags(1) values (now - 1m, 1)"
)
tdSql.execute(
"insert into t1 using stb1 tags(1) values (now - 2m, 2)"
)
tdSql.execute(
"insert into t1 using stb1 tags(1) values (now - 3m, 3)"
)
res = tdSql.getColNameList("select count(*) from t1 interval(1m)")
assert res[0] == 'time'
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册