|
|
|
@ -24,7 +24,30 @@
|
|
|
|
|
#include "tscUtil.h"
|
|
|
|
|
#include "tschemautil.h"
|
|
|
|
|
#include "tsclient.h"
|
|
|
|
|
#include "taos.h"
|
|
|
|
|
#include "tscSubquery.h"
|
|
|
|
|
|
|
|
|
|
#define STR_NOCASE_EQUAL(str1, len1, str2, len2) ((len1 == len2) && 0 == strncasecmp(str1, str2, len1))
|
|
|
|
|
|
|
|
|
|
typedef enum BuildType {
|
|
|
|
|
SCREATE_BUILD_TABLE = 1,
|
|
|
|
|
SCREATE_BUILD_DB = 2,
|
|
|
|
|
} BuildType;
|
|
|
|
|
|
|
|
|
|
typedef enum Stage {
|
|
|
|
|
SCREATE_CALLBACK_QUERY = 1,
|
|
|
|
|
SCREATE_CALLBACK_RETRIEVE = 2,
|
|
|
|
|
} Stage;
|
|
|
|
|
|
|
|
|
|
// support 'show create table'
|
|
|
|
|
typedef struct SCreateBuilder {
|
|
|
|
|
char sTableName[TSDB_TABLE_FNAME_LEN];
|
|
|
|
|
char buf[TSDB_TABLE_FNAME_LEN];
|
|
|
|
|
SSqlObj *pParentSql;
|
|
|
|
|
SSqlObj *pInterSql;
|
|
|
|
|
int32_t (*fp)(void *para, char* result);
|
|
|
|
|
Stage callStage;
|
|
|
|
|
} SCreateBuilder;
|
|
|
|
|
static void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, int16_t type, size_t valueLength);
|
|
|
|
|
|
|
|
|
|
static int32_t getToStringLength(const char *pData, int32_t length, int32_t type) {
|
|
|
|
@ -273,7 +296,505 @@ static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
|
|
|
|
|
tscFieldInfoUpdateOffset(pQueryInfo);
|
|
|
|
|
return tscSetValueToResObj(pSql, rowLen);
|
|
|
|
|
}
|
|
|
|
|
static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengths, int idx, char *result) {
|
|
|
|
|
const char *val = row[idx];
|
|
|
|
|
if (val == NULL) {
|
|
|
|
|
sprintf(result, "%s", TSDB_DATA_NULL_STR);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
uint8_t type = fields[idx].type;
|
|
|
|
|
int32_t length = lengths[idx];
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case TSDB_DATA_TYPE_BOOL:
|
|
|
|
|
sprintf(result, "%s", ((((int)(*((char *)val))) == 1) ? "true" : "false"));
|
|
|
|
|
break;
|
|
|
|
|
case TSDB_DATA_TYPE_TINYINT:
|
|
|
|
|
sprintf(result, "%d", (int)(*((char *)val)));
|
|
|
|
|
break;
|
|
|
|
|
case TSDB_DATA_TYPE_SMALLINT:
|
|
|
|
|
sprintf(result, "%d", (int)(*((short *)val)));
|
|
|
|
|
break;
|
|
|
|
|
case TSDB_DATA_TYPE_INT:
|
|
|
|
|
sprintf(result, "%d", *((int *)val));
|
|
|
|
|
break;
|
|
|
|
|
case TSDB_DATA_TYPE_BIGINT:
|
|
|
|
|
sprintf(result, "%"PRId64, *((int64_t *)val));
|
|
|
|
|
break;
|
|
|
|
|
case TSDB_DATA_TYPE_FLOAT:
|
|
|
|
|
sprintf(result, "%f", GET_FLOAT_VAL(val));
|
|
|
|
|
break;
|
|
|
|
|
case TSDB_DATA_TYPE_DOUBLE:
|
|
|
|
|
sprintf(result, "%f", GET_DOUBLE_VAL(val));
|
|
|
|
|
break;
|
|
|
|
|
case TSDB_DATA_TYPE_NCHAR:
|
|
|
|
|
case TSDB_DATA_TYPE_BINARY:
|
|
|
|
|
memcpy(result, val, length);
|
|
|
|
|
break;
|
|
|
|
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
|
|
|
|
///formatTimestamp(buf, *(int64_t*)val, TSDB_TIME_PRECISION_MICRO);
|
|
|
|
|
//memcpy(result, val, strlen(buf));
|
|
|
|
|
sprintf(result, "%"PRId64, *((int64_t *)val));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tscSCreateCallBack(void *param, TAOS_RES *tres, int code) {
|
|
|
|
|
if (param == NULL || tres == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
SCreateBuilder *builder = (SCreateBuilder *)(param);
|
|
|
|
|
SSqlObj *pParentSql = builder->pParentSql;
|
|
|
|
|
SSqlObj *pSql = (SSqlObj *)tres;
|
|
|
|
|
|
|
|
|
|
SSqlRes *pRes = &pParentSql->res;
|
|
|
|
|
pRes->code = taos_errno(pSql);
|
|
|
|
|
if (pRes->code != TSDB_CODE_SUCCESS) {
|
|
|
|
|
taos_free_result(pSql);
|
|
|
|
|
free(builder);
|
|
|
|
|
tscQueueAsyncRes(pParentSql);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (builder->callStage == SCREATE_CALLBACK_QUERY) {
|
|
|
|
|
taos_fetch_rows_a(tres, tscSCreateCallBack, param);
|
|
|
|
|
builder->callStage = SCREATE_CALLBACK_RETRIEVE;
|
|
|
|
|
} else {
|
|
|
|
|
char *result = calloc(1, TSDB_MAX_BINARY_LEN);
|
|
|
|
|
pRes->code = builder->fp(builder, result);
|
|
|
|
|
|
|
|
|
|
taos_free_result(pSql);
|
|
|
|
|
free(builder);
|
|
|
|
|
free(result);
|
|
|
|
|
|
|
|
|
|
if (pRes->code == TSDB_CODE_SUCCESS) {
|
|
|
|
|
(*pParentSql->fp)(pParentSql->param, pParentSql, code);
|
|
|
|
|
} else {
|
|
|
|
|
tscQueueAsyncRes(pParentSql);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TAOS_ROW tscFetchRow(void *param) {
|
|
|
|
|
SCreateBuilder *builder = (SCreateBuilder *)param;
|
|
|
|
|
if (builder == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
SSqlObj *pSql = builder->pInterSql;
|
|
|
|
|
if (pSql == NULL || pSql->signature != pSql) {
|
|
|
|
|
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SSqlCmd *pCmd = &pSql->cmd;
|
|
|
|
|
SSqlRes *pRes = &pSql->res;
|
|
|
|
|
|
|
|
|
|
if (pRes->qhandle == 0 ||
|
|
|
|
|
pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
|
|
|
|
|
pCmd->command == TSDB_SQL_INSERT) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set the sql object owner
|
|
|
|
|
tscSetSqlOwner(pSql);
|
|
|
|
|
|
|
|
|
|
// current data set are exhausted, fetch more data from node
|
|
|
|
|
if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) &&
|
|
|
|
|
(pCmd->command == TSDB_SQL_RETRIEVE ||
|
|
|
|
|
pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE ||
|
|
|
|
|
pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE ||
|
|
|
|
|
pCmd->command == TSDB_SQL_FETCH ||
|
|
|
|
|
pCmd->command == TSDB_SQL_SHOW ||
|
|
|
|
|
pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
|
|
|
|
|
pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE ||
|
|
|
|
|
pCmd->command == TSDB_SQL_SELECT ||
|
|
|
|
|
pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
|
|
|
|
|
pCmd->command == TSDB_SQL_SERV_STATUS ||
|
|
|
|
|
pCmd->command == TSDB_SQL_CURRENT_DB ||
|
|
|
|
|
pCmd->command == TSDB_SQL_SERV_VERSION ||
|
|
|
|
|
pCmd->command == TSDB_SQL_CLI_VERSION ||
|
|
|
|
|
pCmd->command == TSDB_SQL_CURRENT_USER )) {
|
|
|
|
|
taos_fetch_rows_a(pSql, tscSCreateCallBack, param);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* data = doSetResultRowData(pSql, true);
|
|
|
|
|
|
|
|
|
|
tscClearSqlOwner(pSql);
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) {
|
|
|
|
|
TAOS_ROW row = tscFetchRow(builder);
|
|
|
|
|
SSqlObj* pSql = builder->pInterSql;
|
|
|
|
|
|
|
|
|
|
if (row == NULL) {
|
|
|
|
|
return TSDB_CODE_MND_INVALID_TABLE_NAME;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t* lengths = taos_fetch_lengths(pSql);
|
|
|
|
|
int num_fields = taos_num_fields(pSql);
|
|
|
|
|
TAOS_FIELD *fields = taos_fetch_fields(pSql);
|
|
|
|
|
|
|
|
|
|
char buf[TSDB_COL_NAME_LEN + 16];
|
|
|
|
|
for (int i = 0; i < num_fields; i++) {
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
int32_t ret = tscGetNthFieldResult(row, fields, lengths, i, buf);
|
|
|
|
|
|
|
|
|
|
if (i == 0) {
|
|
|
|
|
snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s", "(");
|
|
|
|
|
}
|
|
|
|
|
if ((fields[i].type == TSDB_DATA_TYPE_NCHAR
|
|
|
|
|
|| fields[i].type == TSDB_DATA_TYPE_BINARY
|
|
|
|
|
|| fields[i].type == TSDB_DATA_TYPE_TIMESTAMP) && 0 == ret) {
|
|
|
|
|
snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "\"%s\",", buf);
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s,", buf);
|
|
|
|
|
}
|
|
|
|
|
if (i == num_fields - 1) {
|
|
|
|
|
sprintf(result + strlen(result) - 1, "%s", ")");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == strlen(result)) {
|
|
|
|
|
return TSDB_CODE_MND_INVALID_TABLE_NAME;
|
|
|
|
|
}
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// build 'show create table/database' result fields
|
|
|
|
|
static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const char *ddl) {
|
|
|
|
|
int32_t rowLen = 0;
|
|
|
|
|
int16_t ddlLen = strlen(ddl);
|
|
|
|
|
SColumnIndex index = {0};
|
|
|
|
|
pSql->cmd.numOfCols = 2;
|
|
|
|
|
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
|
|
|
|
|
|
|
|
|
TAOS_FIELD f;
|
|
|
|
|
if (type == SCREATE_BUILD_TABLE) {
|
|
|
|
|
f.type = TSDB_DATA_TYPE_BINARY;
|
|
|
|
|
f.bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE;
|
|
|
|
|
tstrncpy(f.name, "Table", sizeof(f.name));
|
|
|
|
|
} else {
|
|
|
|
|
f.type = TSDB_DATA_TYPE_BINARY;
|
|
|
|
|
f.bytes = (TSDB_DB_NAME_LEN - 1) + VARSTR_HEADER_SIZE;
|
|
|
|
|
tstrncpy(f.name, "Database", sizeof(f.name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SFieldSupInfo* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
|
|
|
|
pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
|
|
|
|
f.bytes, f.bytes - VARSTR_HEADER_SIZE, false);
|
|
|
|
|
|
|
|
|
|
rowLen += f.bytes;
|
|
|
|
|
|
|
|
|
|
f.bytes = (int16_t)(ddlLen + VARSTR_HEADER_SIZE);
|
|
|
|
|
f.type = TSDB_DATA_TYPE_BINARY;
|
|
|
|
|
if (type == SCREATE_BUILD_TABLE) {
|
|
|
|
|
tstrncpy(f.name, "Create Table", sizeof(f.name));
|
|
|
|
|
} else {
|
|
|
|
|
tstrncpy(f.name, "Create Database", sizeof(f.name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
|
|
|
|
pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
|
|
|
|
(int16_t)(ddlLen + VARSTR_HEADER_SIZE), ddlLen, false);
|
|
|
|
|
|
|
|
|
|
rowLen += ddlLen + VARSTR_HEADER_SIZE;
|
|
|
|
|
|
|
|
|
|
return rowLen;
|
|
|
|
|
}
|
|
|
|
|
static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) {
|
|
|
|
|
SSqlRes *pRes = &pSql->res;
|
|
|
|
|
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
int32_t numOfRows = 1;
|
|
|
|
|
if (strlen(ddl) == 0) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
tscInitResObjForLocalQuery(pSql, numOfRows, rowLen);
|
|
|
|
|
|
|
|
|
|
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
|
|
|
|
|
char* dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * numOfRows;
|
|
|
|
|
STR_WITH_MAXSIZE_TO_VARSTR(dst, tableName, pField->bytes);
|
|
|
|
|
|
|
|
|
|
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
|
|
|
|
|
dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * numOfRows;
|
|
|
|
|
STR_WITH_MAXSIZE_TO_VARSTR(dst, ddl, pField->bytes);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) {
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result);
|
|
|
|
|
|
|
|
|
|
tscFieldInfoUpdateOffset(pQueryInfo);
|
|
|
|
|
return tscSCreateSetValueToResObj(pSql, rowLen, str, result);
|
|
|
|
|
}
|
|
|
|
|
int32_t tscRebuildCreateTableStatement(void *param,char *result) {
|
|
|
|
|
SCreateBuilder *builder = (SCreateBuilder *)param;
|
|
|
|
|
int32_t code = TSDB_CODE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
char *buf = calloc(1,TSDB_MAX_BINARY_LEN);
|
|
|
|
|
if (buf == NULL) {
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
code = tscGetTableTagValue(builder, buf);
|
|
|
|
|
if (code == TSDB_CODE_SUCCESS) {
|
|
|
|
|
snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "CREATE TABLE %s USING %s TAGS %s", builder->buf, builder->sTableName, buf);
|
|
|
|
|
code = tscSCreateBuildResult(builder->pParentSql, SCREATE_BUILD_TABLE, builder->buf, result);
|
|
|
|
|
}
|
|
|
|
|
free(buf);
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t tscGetDBInfo(SCreateBuilder *builder, char *result) {
|
|
|
|
|
TAOS_ROW row = tscFetchRow(builder);
|
|
|
|
|
if (row == NULL) {
|
|
|
|
|
return TSDB_CODE_MND_DB_NOT_SELECTED;
|
|
|
|
|
}
|
|
|
|
|
const char *showColumns[] = {"REPLICA", "QUORUM", "DAYS", "KEEP", "BLOCKS", NULL};
|
|
|
|
|
|
|
|
|
|
SSqlObj *pSql = builder->pInterSql;
|
|
|
|
|
TAOS_FIELD *fields = taos_fetch_fields(pSql);
|
|
|
|
|
int num_fields = taos_num_fields(pSql);
|
|
|
|
|
|
|
|
|
|
char buf[TSDB_DB_NAME_LEN + 64] = {0};
|
|
|
|
|
do {
|
|
|
|
|
int32_t* lengths = taos_fetch_lengths(pSql);
|
|
|
|
|
int32_t ret = tscGetNthFieldResult(row, fields, lengths, 0, buf);
|
|
|
|
|
if (0 == ret && STR_NOCASE_EQUAL(buf, strlen(buf), builder->buf, strlen(builder->buf))) {
|
|
|
|
|
snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "CREATE DATABASE %s", buf);
|
|
|
|
|
for (int i = 1; i < num_fields; i++) {
|
|
|
|
|
for (int j = 0; showColumns[j] != NULL; j++) {
|
|
|
|
|
if (STR_NOCASE_EQUAL(fields[i].name, strlen(fields[i].name), showColumns[j], strlen(showColumns[j]))) {
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
ret = tscGetNthFieldResult(row, fields, lengths, i, buf);
|
|
|
|
|
if (ret == 0) {
|
|
|
|
|
snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), " %s %s", showColumns[j], buf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
row = tscFetchRow(builder);
|
|
|
|
|
} while (row != NULL);
|
|
|
|
|
|
|
|
|
|
if (0 == strlen(result)) {
|
|
|
|
|
return TSDB_CODE_MND_DB_NOT_SELECTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
int32_t tscRebuildCreateDBStatement(void *param,char *result) {
|
|
|
|
|
SCreateBuilder *builder = (SCreateBuilder *)param;
|
|
|
|
|
int32_t code = TSDB_CODE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
char *buf = calloc(1, TSDB_MAX_BINARY_LEN);
|
|
|
|
|
if (buf == NULL) {
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
code = tscGetDBInfo(param, buf);
|
|
|
|
|
if (code == TSDB_CODE_SUCCESS) {
|
|
|
|
|
code = tscSCreateBuildResult(builder->pParentSql, SCREATE_BUILD_DB, builder->buf, buf);
|
|
|
|
|
}
|
|
|
|
|
free(buf);
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) {
|
|
|
|
|
char *buf = (char *)malloc(TSDB_MAX_BINARY_LEN);
|
|
|
|
|
if (buf == NULL) {
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
buf[0] = 0;
|
|
|
|
|
|
|
|
|
|
STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->pTableMeta;
|
|
|
|
|
if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
|
|
|
|
|
pMeta->tableType == TSDB_STREAM_TABLE) {
|
|
|
|
|
free(buf);
|
|
|
|
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SSchema *pTagsSchema = tscGetTableTagSchema(pMeta);
|
|
|
|
|
int32_t numOfTags = tscGetNumOfTags(pMeta);
|
|
|
|
|
for (int32_t i = 0; i < numOfTags; i++) {
|
|
|
|
|
if (i != numOfTags - 1) {
|
|
|
|
|
snprintf(buf + strlen(buf), TSDB_MAX_BINARY_LEN - strlen(buf), "%s,", pTagsSchema[i].name);
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(buf + strlen(buf), TSDB_MAX_BINARY_LEN - strlen(buf), "%s", pTagsSchema[i].name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*result = buf;
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
|
|
|
|
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
|
|
|
|
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
|
|
|
|
|
|
|
|
|
SSqlObj *pInterSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
|
|
|
|
if (pInterSql == NULL) {
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SCreateBuilder *param = (SCreateBuilder *)malloc(sizeof(SCreateBuilder));
|
|
|
|
|
if (param == NULL) {
|
|
|
|
|
free(pInterSql);
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char fullName[TSDB_TABLE_FNAME_LEN] = {0};
|
|
|
|
|
extractDBName(pTableMetaInfo->name, fullName);
|
|
|
|
|
extractTableName(pMeta->sTableId, param->sTableName);
|
|
|
|
|
snprintf(fullName + strlen(fullName), TSDB_TABLE_FNAME_LEN - strlen(fullName), ".%s", param->sTableName);
|
|
|
|
|
extractTableName(pTableMetaInfo->name, param->buf);
|
|
|
|
|
|
|
|
|
|
//tstrncpy(param->tableName, pTableMetaInfo->name, TSDB_TABLE_FNAME_LEN);
|
|
|
|
|
param->pParentSql = pSql;
|
|
|
|
|
param->pInterSql = pInterSql;
|
|
|
|
|
param->fp = tscRebuildCreateTableStatement;
|
|
|
|
|
param->callStage = SCREATE_CALLBACK_QUERY;
|
|
|
|
|
|
|
|
|
|
char *query = (char *)calloc(1, TSDB_MAX_BINARY_LEN);
|
|
|
|
|
if (query == NULL) {
|
|
|
|
|
free(param);
|
|
|
|
|
free(pInterSql);
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *columns = NULL;
|
|
|
|
|
int32_t code = tscGetTableTagColumnName(pSql, &columns) ;
|
|
|
|
|
if (code != TSDB_CODE_SUCCESS) {
|
|
|
|
|
free(param);
|
|
|
|
|
free(pInterSql);
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snprintf(query + strlen(query), TSDB_MAX_BINARY_LEN - strlen(query), "SELECT %s FROM %s WHERE TBNAME IN(\'%s\')", columns, fullName, param->buf);
|
|
|
|
|
doAsyncQuery(pSql->pTscObj, pInterSql, tscSCreateCallBack, param, query, strlen(query));
|
|
|
|
|
free(query);
|
|
|
|
|
free(columns);
|
|
|
|
|
|
|
|
|
|
return TSDB_CODE_TSC_ACTION_IN_PROGRESS;
|
|
|
|
|
}
|
|
|
|
|
static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
|
|
|
|
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
|
|
|
|
|
|
|
|
|
int32_t numOfRows = tscGetNumOfColumns(pMeta);
|
|
|
|
|
SSchema *pSchema = tscGetTableSchema(pMeta);
|
|
|
|
|
|
|
|
|
|
char *result = ddl;
|
|
|
|
|
sprintf(result, "create table %s (", tableName);
|
|
|
|
|
for (int32_t i = 0; i < numOfRows; ++i) {
|
|
|
|
|
uint8_t type = pSchema[i].type;
|
|
|
|
|
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
|
|
|
|
sprintf(result + strlen(result), "%s %s(%d),", pSchema[i].name,tDataTypeDesc[pSchema[i].type].aName,pSchema->bytes);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(result + strlen(result), "%s %s,", pSchema[i].name, tDataTypeDesc[pSchema[i].type].aName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sprintf(result + strlen(result) - 1, "%s", ")");
|
|
|
|
|
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
|
|
|
|
char *result = ddl;
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
|
|
|
|
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
|
|
|
|
|
|
|
|
|
int32_t numOfRows = tscGetNumOfColumns(pMeta);
|
|
|
|
|
int32_t totalRows = numOfRows + tscGetNumOfTags(pMeta);
|
|
|
|
|
SSchema *pSchema = tscGetTableSchema(pMeta);
|
|
|
|
|
|
|
|
|
|
sprintf(result, "create table %s (", tableName);
|
|
|
|
|
for (int32_t i = 0; i < numOfRows; ++i) {
|
|
|
|
|
uint8_t type = pSchema[i].type;
|
|
|
|
|
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
|
|
|
|
sprintf(result + strlen(result), "%s %s(%d),", pSchema[i].name,tDataTypeDesc[pSchema[i].type].aName,pSchema->bytes);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(result + strlen(result), "%s %s,", pSchema[i].name, tDataTypeDesc[type].aName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sprintf(result + strlen(result) - 1, "%s ", ")");
|
|
|
|
|
|
|
|
|
|
sprintf(result + strlen(result), "TAGS (");
|
|
|
|
|
for (int32_t i = numOfRows; i < totalRows; i++) {
|
|
|
|
|
uint8_t type = pSchema[i].type;
|
|
|
|
|
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
|
|
|
|
sprintf(result + strlen(result), "%s %s(%d),", pSchema[i].name,tDataTypeDesc[pSchema[i].type].aName,pSchema->bytes);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(result + strlen(result), "%s %s,", pSchema[i].name, tDataTypeDesc[type].aName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
sprintf(result + strlen(result) - 1, "%s", ")");
|
|
|
|
|
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
|
|
|
|
assert(pTableMetaInfo->pTableMeta != NULL);
|
|
|
|
|
|
|
|
|
|
char tableName[TSDB_TABLE_NAME_LEN] = {0};
|
|
|
|
|
extractTableName(pTableMetaInfo->name, tableName);
|
|
|
|
|
|
|
|
|
|
char result[TSDB_MAX_BYTES_PER_ROW] = {0};
|
|
|
|
|
int32_t code = TSDB_CODE_SUCCESS;
|
|
|
|
|
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
|
|
|
|
code = tscRebuildDDLForSuperTable(pSql, tableName, result);
|
|
|
|
|
} else if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
|
|
|
|
|
code = tscRebuildDDLForNormalTable(pSql, tableName, result);
|
|
|
|
|
} else if (UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) {
|
|
|
|
|
code = tscRebuildDDLForSubTable(pSql, tableName, result);
|
|
|
|
|
} else {
|
|
|
|
|
code = TSDB_CODE_TSC_INVALID_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (code != TSDB_CODE_SUCCESS) {
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
return tscSCreateBuildResult(pSql, SCREATE_BUILD_TABLE, tableName, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
|
|
|
|
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
|
|
|
|
|
|
|
|
|
SSqlObj *pInterSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
|
|
|
|
if (pInterSql == NULL) {
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SCreateBuilder *param = (SCreateBuilder *)malloc(sizeof(SCreateBuilder));
|
|
|
|
|
if (param == NULL) {
|
|
|
|
|
free(pInterSql);
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
extractTableName(pTableMetaInfo->name, param->buf);
|
|
|
|
|
param->pParentSql = pSql;
|
|
|
|
|
param->pInterSql = pInterSql;
|
|
|
|
|
param->fp = tscRebuildCreateDBStatement;
|
|
|
|
|
param->callStage = SCREATE_CALLBACK_QUERY;
|
|
|
|
|
|
|
|
|
|
const char *query = "show databases";
|
|
|
|
|
doAsyncQuery(pSql->pTscObj, pInterSql, tscSCreateCallBack, param, query, strlen(query));
|
|
|
|
|
return TSDB_CODE_TSC_ACTION_IN_PROGRESS;
|
|
|
|
|
}
|
|
|
|
|
static int32_t tscProcessCurrentUser(SSqlObj *pSql) {
|
|
|
|
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
|
|
|
|
|
|
|
@ -337,6 +858,7 @@ static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
|
|
|
|
char* vx = calloc(1, pExpr->resBytes);
|
|
|
|
|
if (vx == NULL) {
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STR_WITH_SIZE_TO_VARSTR(vx, v, (VarDataLenT)t);
|
|
|
|
@ -344,6 +866,7 @@ static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
|
|
|
|
|
|
|
|
|
free(vx);
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
|
|
|
@ -358,6 +881,7 @@ static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
|
|
|
|
char* v = calloc(1, pExpr->resBytes);
|
|
|
|
|
if (v == NULL) {
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STR_WITH_SIZE_TO_VARSTR(v, version, (VarDataLenT)t);
|
|
|
|
@ -365,6 +889,7 @@ static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
|
|
|
|
|
|
|
|
|
free(v);
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t tscProcessServStatus(SSqlObj *pSql) {
|
|
|
|
@ -429,6 +954,10 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|
|
|
|
*/
|
|
|
|
|
pRes->qhandle = 0x1;
|
|
|
|
|
pRes->numOfRows = 0;
|
|
|
|
|
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE) {
|
|
|
|
|
pRes->code = tscProcessShowCreateTable(pSql);
|
|
|
|
|
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
|
|
|
|
|
pRes->code = tscProcessShowCreateDatabase(pSql);
|
|
|
|
|
} else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
|
|
|
|
|
taosCacheEmpty(tscCacheHandle);
|
|
|
|
|
pRes->code = TSDB_CODE_SUCCESS;
|
|
|
|
@ -448,12 +977,13 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// keep the code in local variable in order to avoid invalid read in case of async query
|
|
|
|
|
|
|
|
|
|
int32_t code = pRes->code;
|
|
|
|
|
if (code == TSDB_CODE_SUCCESS) {
|
|
|
|
|
(*pSql->fp)(pSql->param, pSql, code);
|
|
|
|
|
} else if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS){
|
|
|
|
|
} else {
|
|
|
|
|
tscQueueAsyncRes(pSql);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|