0

根据TDengine的文件,

The maximum length of a column name is 64.

我想在源代码中将它从 64 更改为 100,并构建一个新版本。

然后我找到了 taosdef.h,并对其进行了更改:

#define TSDB_COL_NAME_LEN   100

然后我成功构建了它。

我试图创建一个列名超过 64 的表,但我失败了。

 invalid column name 

我如何解决它?

4

1 回答 1

0

产生该错误(或类似错误)的方法有很多。纠正一个并不意味着也没有其他问题。

请显示导致错误的执行的确切语句(以及确切/完整的错误)。

添加断点或以其他方式跟踪执行以查找问题的根源。

问题可能在以下某处(可能是 validateColumnName),但如果上述细节不准确,情况可能会改变:

validateStateWindowNode
validateSessionNode
validateTableColumnInfo  <===== which then calls validateColumnName
validateOneColumn
handleArithmeticExpr
addProjectionExprAndResultField
doGetColumnIndexByName
validateGroupbyNode
checkAndSetJoinCondInfo
doAddJoinTagsColumnsIntoTagList
validateOrderbyNode
setAlterTableInfo


./src/client/src/tscSQLParser.c

validateTableColumnInfo
    if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) {
      invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
      return false;
    }


int32_t validateColumnName(char* name) {
  bool ret = taosIsKeyWordToken(name, (int32_t)strlen(name));
  if (ret) {
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

  SStrToken token = {.z = name};
  token.n = tGetToken(name, &token.type);

  if (token.type != TK_STRING && token.type != TK_ID) {
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

  if (token.type == TK_STRING) {
    strdequote(token.z);
    strntolower(token.z, token.z, token.n);
    token.n = (uint32_t)strtrim(token.z);

    int32_t k = tGetToken(token.z, &token.type);
    if (k != token.n) {
      return TSDB_CODE_TSC_INVALID_OPERATION;
    }

    return validateColumnName(token.z);
  } else {
    if (isNumber(&token)) {
      return TSDB_CODE_TSC_INVALID_OPERATION;
    }
  }

  return TSDB_CODE_SUCCESS;
}


$ find . -name "*.[ch]" | xargs grep "taosIsKeyWordToken"
./src/client/src/tscSQLParser.c:  bool ret = taosIsKeyWordToken(name, (int32_t)strlen(name));
./src/util/inc/ttoken.h:bool taosIsKeyWordToken(const char *z, int32_t len);
./src/util/src/ttokenizer.c:bool taosIsKeyWordToken(const char* z, int32_t len) {

./src/util/src/ttokenizer.c:bool taosIsKeyWordToken(const char* z, int32_t len) {


./src/util/src/ttokenizer.c

bool taosIsKeyWordToken(const char* z, int32_t len) {
  return (tKeywordCode((char*)z, len) != TK_ID);
}

static int32_t tKeywordCode(const char* z, int n) {
  pthread_once(&keywordsHashTableInit, doInitKeywordsTable);
  
  char key[512] = {0};
  if (n > tListLen(key)) { // too long token, can not be any other token type
    return TK_ID;
  }
  
  for (int32_t j = 0; j < n; ++j) {
    if (z[j] >= 'a' && z[j] <= 'z') {
      key[j] = (char)(z[j] & 0xDF);  // to uppercase and set the null-terminated
    } else {
      key[j] = z[j];
    }
  }

  SKeyword** pKey = (SKeyword**)taosHashGet(keywordHashTable, key, n);
  return (pKey != NULL)? (*pKey)->type:TK_ID;
}
于 2021-08-23T11:18:39.560 回答