diff --git a/.eslintrc b/.eslintrc index be1f758d..245baaf8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -66,7 +66,7 @@ ], "complexity": [ "error", - 30 + 35 ], "space-infix-ops": 2, "consistent-return": 0, diff --git a/pegjs/athena.pegjs b/pegjs/athena.pegjs index 442c0c99..ed9f8192 100644 --- a/pegjs/athena.pegjs +++ b/pegjs/athena.pegjs @@ -792,7 +792,7 @@ create_option_character_set_kw return 'CHARACTER SET' } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, diff --git a/pegjs/bigquery.pegjs b/pegjs/bigquery.pegjs index 92896c92..6ddb6b88 100644 --- a/pegjs/bigquery.pegjs +++ b/pegjs/bigquery.pegjs @@ -1276,7 +1276,7 @@ create_like_table_simple } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:literal_string { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, diff --git a/pegjs/db2.pegjs b/pegjs/db2.pegjs index 14bf2bc4..519c4354 100644 --- a/pegjs/db2.pegjs +++ b/pegjs/db2.pegjs @@ -853,7 +853,7 @@ create_option_character_set_kw return 'CHARACTER SET' } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, diff --git a/pegjs/flinksql.pegjs b/pegjs/flinksql.pegjs index 1e277374..9b33ed1a 100644 --- a/pegjs/flinksql.pegjs +++ b/pegjs/flinksql.pegjs @@ -1444,7 +1444,7 @@ create_option_character_set_kw return 'CHARACTER SET' } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, diff --git a/pegjs/hive.pegjs b/pegjs/hive.pegjs index 57e092de..bda0a29c 100644 --- a/pegjs/hive.pegjs +++ b/pegjs/hive.pegjs @@ -792,7 +792,7 @@ create_option_character_set_kw return 'CHARACTER SET' } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, diff --git a/pegjs/mariadb.pegjs b/pegjs/mariadb.pegjs index b00bdecb..e2c2076b 100644 --- a/pegjs/mariadb.pegjs +++ b/pegjs/mariadb.pegjs @@ -710,7 +710,7 @@ column_definition_opt / ck:check_constraint_definition { return { check: ck } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { return { character_set: { type: t, value: v, symbol: s }} } @@ -1394,7 +1394,7 @@ create_option_character_set_kw return 'CHARACTER SET' } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, @@ -3106,7 +3106,7 @@ count_arg star_expr = "*" { return { type: 'star', value: '*' }; } convert_args - = c:proc_primary __ COMMA __ ch:character_string_type __ cs:create_option_character_set_kw __ v:ident_name { + = c:proc_primary __ COMMA __ ch:(character_string_type / datetime_type) __ cs:create_option_character_set_kw __ v:ident_without_kw_type { const { dataType, length } = ch let dataTypeStr = dataType if (length !== undefined) dataTypeStr = `${dataTypeStr}(${length})` @@ -3116,8 +3116,12 @@ convert_args c, { type: 'origin', - value: `${dataTypeStr} ${cs} ${v}` - } + value: dataTypeStr, + suffix: { + prefix: cs, + ...v, + } + }, ] } } @@ -3243,7 +3247,7 @@ scalar_func / KW_SYSTEM_USER cast_expr - = c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ ch:character_string_type __ cs:create_option_character_set_kw __ v:ident_name __ RPAREN __ ca:collate_expr? { + = c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ ch:character_string_type __ cs:create_option_character_set_kw __ v:ident_without_kw_type __ RPAREN __ ca:collate_expr? { const { dataType, length } = ch let dataTypeStr = dataType if (length !== undefined) dataTypeStr = `${dataTypeStr}(${length})` @@ -3253,7 +3257,8 @@ cast_expr expr: e, symbol: 'as', target: { - dataType: `${dataTypeStr} ${cs} ${v.toUpperCase()}` + dataType: dataTypeStr, + suffix: [{ type: 'origin', value: cs }, v], }, collate: ca, }; diff --git a/pegjs/mysql.pegjs b/pegjs/mysql.pegjs index 7d83c26e..ee0afe92 100644 --- a/pegjs/mysql.pegjs +++ b/pegjs/mysql.pegjs @@ -908,7 +908,7 @@ column_definition_opt / ck:check_constraint_definition { return { check: ck } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { return { character_set: { type: t, value: v, symbol: s }} } / g:generated { @@ -1615,7 +1615,7 @@ create_option_character_set_kw return 'CHARACTER SET' } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, @@ -3391,7 +3391,7 @@ star_expr = "*" { return { type: 'star', value: '*' }; } convert_args - = c:proc_primary __ COMMA __ ch:(character_string_type / datetime_type) __ cs:create_option_character_set_kw __ v:ident_name { + = c:proc_primary __ COMMA __ ch:(character_string_type / datetime_type) __ cs:create_option_character_set_kw __ v:ident_without_kw_type { const { dataType, length } = ch let dataTypeStr = dataType if (length !== undefined) dataTypeStr = `${dataTypeStr}(${length})` @@ -3401,8 +3401,12 @@ convert_args c, { type: 'origin', - value: `${dataTypeStr} ${cs} ${v}` - } + value: dataTypeStr, + suffix: { + prefix: cs, + ...v, + } + }, ] } } @@ -3528,7 +3532,7 @@ scalar_func / KW_SYSTEM_USER cast_expr - = c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ ch:character_string_type __ cs:create_option_character_set_kw __ v:ident_name __ RPAREN __ ca:collate_expr? { + = c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ ch:character_string_type __ cs:create_option_character_set_kw __ v:ident_without_kw_type __ RPAREN __ ca:collate_expr? { const { dataType, length } = ch let dataTypeStr = dataType if (length !== undefined) dataTypeStr = `${dataTypeStr}(${length})` @@ -3538,7 +3542,8 @@ cast_expr expr: e, symbol: 'as', target: { - dataType: `${dataTypeStr} ${cs} ${v.toUpperCase()}` + dataType: dataTypeStr, + suffix: [{ type: 'origin', value: cs }, v], }, collate: ca, }; diff --git a/pegjs/noql.pegjs b/pegjs/noql.pegjs index cae85f2c..9248f379 100644 --- a/pegjs/noql.pegjs +++ b/pegjs/noql.pegjs @@ -1144,8 +1144,7 @@ column_definition_opt // => { reference_definition: reference_definition; } return { reference_definition: re } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { - // => { character_set: collate_expr } + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { return { character_set: { type: t, value: v, symbol: s }} } @@ -2037,11 +2036,11 @@ create_option_character_set_kw } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { /* => { keyword: 'character set' | 'charset' | 'collate' | 'default character set' | 'default charset' | 'default collate'; symbol: '='; - value: ident_name; + value: ident_without_kw_type; } */ return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), diff --git a/pegjs/postgresql.pegjs b/pegjs/postgresql.pegjs index d42060e5..c01bb084 100644 --- a/pegjs/postgresql.pegjs +++ b/pegjs/postgresql.pegjs @@ -1275,8 +1275,8 @@ column_definition_opt // => { check: check_constraint_definition; } return { check: ck } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { - // => { character_set: collate_expr } + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { + // => { character_set: { type: 'CHARACTER SET'; symbol: '=' | null; value: ident_without_kw_type; } } return { character_set: { type: t, value: v, symbol: s }} } @@ -2211,11 +2211,11 @@ create_option_character_set_kw } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { /* => { keyword: 'character set' | 'charset' | 'collate' | 'default character set' | 'default charset' | 'default collate'; symbol: '='; - value: ident_name; + value: ident_without_kw_type; } */ return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), diff --git a/pegjs/redshift.pegjs b/pegjs/redshift.pegjs index f4148423..07f0b3fb 100644 --- a/pegjs/redshift.pegjs +++ b/pegjs/redshift.pegjs @@ -1156,8 +1156,7 @@ column_definition_opt // => { reference_definition: reference_definition; } return { reference_definition: re } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { - // => { character_set: collate_expr } + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { return { character_set: { type: t, value: v, symbol: s }} } @@ -2049,11 +2048,11 @@ create_option_character_set_kw } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { /* => { keyword: 'character set' | 'charset' | 'collate' | 'default character set' | 'default charset' | 'default collate'; symbol: '='; - value: ident_name; + value: ident_without_kw_type; } */ return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), diff --git a/pegjs/snowflake.pegjs b/pegjs/snowflake.pegjs index 603e91b4..c6a4979c 100644 --- a/pegjs/snowflake.pegjs +++ b/pegjs/snowflake.pegjs @@ -893,7 +893,7 @@ column_definition_opt // => { reference_definition: reference_definition; } return { reference_definition: re } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { // => { character_set: collate_expr } return { character_set: { type: t, value: v, symbol: s }} } @@ -1777,7 +1777,7 @@ create_option_character_set_kw } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { /* => { keyword: 'character set' | 'charset' | 'collate' | 'default character set' | 'default charset' | 'default collate'; symbol: '='; diff --git a/pegjs/sqlite.pegjs b/pegjs/sqlite.pegjs index 4a931a43..f72885a3 100644 --- a/pegjs/sqlite.pegjs +++ b/pegjs/sqlite.pegjs @@ -530,7 +530,7 @@ column_definition_opt / ck:check_constraint_definition { return { check: ck } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { return { character_set: { type: t, value: v, symbol: s }} } @@ -1092,7 +1092,7 @@ create_option_character_set_kw return 'CHARACTER SET' } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, diff --git a/pegjs/transactsql.pegjs b/pegjs/transactsql.pegjs index b4987ef4..a1f7d49e 100644 --- a/pegjs/transactsql.pegjs +++ b/pegjs/transactsql.pegjs @@ -511,7 +511,7 @@ column_definition_opt / re:reference_definition { return { reference_definition: re } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { return { character_set: { type: t, value: v, symbol: s }} } @@ -1155,7 +1155,7 @@ create_option_character_set_kw return 'CHARACTER SET' } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), symbol: s, diff --git a/pegjs/trino.pegjs b/pegjs/trino.pegjs index 6181bf9c..06e0c25f 100644 --- a/pegjs/trino.pegjs +++ b/pegjs/trino.pegjs @@ -904,7 +904,7 @@ column_definition_opt // => { reference_definition: reference_definition; } return { reference_definition: re } } - / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_name { + / t:create_option_character_set_kw __ s:KW_ASSIGIN_EQUAL? __ v:ident_without_kw_type { // => { character_set: collate_expr } return { character_set: { type: t, value: v, symbol: s }} } @@ -1788,11 +1788,11 @@ create_option_character_set_kw } create_option_character_set - = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_name { + = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type { /* => { keyword: 'character set' | 'charset' | 'collate' | 'default character set' | 'default charset' | 'default collate'; symbol: '='; - value: ident_name; + value: ident_without_kw_type; } */ return { keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(), diff --git a/src/func.js b/src/func.js index f3f3359e..680dd47f 100644 --- a/src/func.js +++ b/src/func.js @@ -29,7 +29,7 @@ function castToSQL(expr) { let str = targetExpr ? exprToSQL(targetExpr) : '' if (length != null) str = scale ? `${length}, ${scale}` : length if (parentheses) str = `(${str})` - if (dataTypeSuffix && dataTypeSuffix.length) str += ` ${dataTypeSuffix.join(' ')}` + if (dataTypeSuffix && dataTypeSuffix.length) str += ` ${dataTypeSuffix.map(literalToSQL).join(' ')}` let prefix = exprToSQL(expression) let symbolChar = '::' let suffix = '' diff --git a/src/tables.js b/src/tables.js index 185dc7a5..e8a24597 100644 --- a/src/tables.js +++ b/src/tables.js @@ -169,7 +169,7 @@ function tableOptionToSQL(tableOption) { const { keyword, symbol, value } = tableOption const sql = [keyword.toUpperCase()] if (symbol) sql.push(symbol) - let val = value + let val = literalToSQL(value) switch (keyword) { case 'partition by': case 'default collate': diff --git a/src/util.js b/src/util.js index 5fb88b8a..fdc231e1 100644 --- a/src/util.js +++ b/src/util.js @@ -174,16 +174,6 @@ function identifierToSql(ident, isDual) { } } -function commonTypeValue(opt) { - const result = [] - if (!opt) return result - const { type, symbol, value } = opt - result.push(type.toUpperCase()) - if (symbol) result.push(symbol) - result.push(value.toUpperCase()) - return result -} - function toUpper(val) { if (!val) return return val.toUpperCase() @@ -197,7 +187,7 @@ function literalToSQL(literal) { if (!literal) return let { prefix } = literal const { type, parentheses, suffix, value } = literal - let str = typeof literal === 'string' ? literal : value + let str = typeof literal === 'object' ? value : literal switch (type) { case 'backticks_quote_string': str = `\`${escape(value)}\`` @@ -258,11 +248,23 @@ function literalToSQL(literal) { const result = [] if (prefix) result.push(toUpper(prefix)) result.push(str) - if (suffix) result.push(typeof suffix === 'object' && suffix.collate ? commonTypeValue(suffix.collate).join(' ') : toUpper(suffix)) + if (suffix) { + if (typeof suffix === 'string') result.push(suffix) + if (typeof suffix === 'object') { + if (suffix.collate) result.push([toUpper(suffix.collate.type), suffix.collate.symbol, toUpper(suffix.collate.value)].filter(hasVal).join(' ')) + else result.push(literalToSQL(suffix)) + } + } str = result.join(' ') return parentheses ? `(${str})` : str } +function commonTypeValue(opt) { + if (!opt) return [] + const { type, symbol, value } = opt + return [type.toUpperCase(), symbol, typeof value === 'string' ? value.toUpperCase() : literalToSQL(value)].filter(hasVal) +} + function replaceParams(ast, params) { return replaceParamsInner(JSON.parse(JSON.stringify(ast)), params) } diff --git a/test/ast.spec.js b/test/ast.spec.js index 86594e3f..c35635bc 100644 --- a/test/ast.spec.js +++ b/test/ast.spec.js @@ -202,7 +202,7 @@ describe('AST', () => { ], 'char casts': [ `SELECT CAST(test AS CHAR CHARACTER SET utf8mb4) COLLATE utf8mb4_bin;`, - 'SELECT CAST(`test` AS CHAR CHARACTER SET UTF8MB4) COLLATE UTF8MB4_BIN' + 'SELECT CAST(`test` AS CHAR CHARACTER SET utf8mb4) COLLATE UTF8MB4_BIN' ], 'time casts': [ "SELECT CAST('12:31:41.8418443' AS TIME(6)) AS `time`;", diff --git a/test/create.spec.js b/test/create.spec.js index aae23c1b..9a6881a9 100644 --- a/test/create.spec.js +++ b/test/create.spec.js @@ -55,7 +55,7 @@ describe('create', () => { compCode varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '我是comment', compCode2 varchar(255) CHARACTER SET = utf8 COLLATE = utf8_general_ci NOT NULL COMMENT '我是comment' ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '我是comment' ROW_FORMAT = Dynamic`)) - .to.equal("CREATE TABLE `comp` (`id` INT(11) NOT NULL AUTO_INCREMENT, `compCode` VARCHAR(255) NOT NULL COMMENT '我是comment' CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI, `compCode2` VARCHAR(255) NOT NULL COMMENT '我是comment' CHARACTER SET = UTF8 COLLATE = UTF8_GENERAL_CI) ENGINE = INNODB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '我是comment' ROW_FORMAT = DYNAMIC"); + .to.equal("CREATE TABLE `comp` (`id` INT(11) NOT NULL AUTO_INCREMENT, `compCode` VARCHAR(255) NOT NULL COMMENT '我是comment' CHARACTER SET utf8 COLLATE UTF8_GENERAL_CI, `compCode2` VARCHAR(255) NOT NULL COMMENT '我是comment' CHARACTER SET = utf8 COLLATE = UTF8_GENERAL_CI) ENGINE = INNODB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '我是comment' ROW_FORMAT = DYNAMIC"); }) it('should support create temporary table', () => { @@ -133,7 +133,7 @@ describe('create', () => { it('should support generated columns', () =>{ expect(getParsedSql(`CREATE TABLE contacts (id INT KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, fullname varchar(101) CHARACTER SET latin1 COLLATE latin1_general_cs AS (CONCAT(first_name,' ',last_name)) STORED NOT NULL);`)) - .to.equal("CREATE TABLE `contacts` (`id` INT KEY, `first_name` VARCHAR(50) NOT NULL, `last_name` VARCHAR(50) NOT NULL, `fullname` VARCHAR(101) NOT NULL CHARACTER SET LATIN1 COLLATE LATIN1_GENERAL_CS AS (CONCAT(`first_name`, ' ', `last_name`)) STORED)"); + .to.equal("CREATE TABLE `contacts` (`id` INT KEY, `first_name` VARCHAR(50) NOT NULL, `last_name` VARCHAR(50) NOT NULL, `fullname` VARCHAR(101) NOT NULL CHARACTER SET latin1 COLLATE LATIN1_GENERAL_CS AS (CONCAT(`first_name`, ' ', `last_name`)) STORED)"); expect(getParsedSql(`CREATE TABLE contacts (id INT KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, fullname varchar(101) AS (CONCAT(first_name,' ',last_name)) STORED);`)) .to.equal("CREATE TABLE `contacts` (`id` INT KEY, `first_name` VARCHAR(50) NOT NULL, `last_name` VARCHAR(50) NOT NULL, `fullname` VARCHAR(101) AS (CONCAT(`first_name`, ' ', `last_name`)) STORED)"); @@ -144,7 +144,7 @@ describe('create', () => { it('should support generated columns with generated always', () =>{ expect(getParsedSql(`CREATE TABLE contacts (id INT KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, fullname varchar(101) CHARACTER SET latin1 COLLATE latin1_general_cs GENERATED ALWAYS AS (CONCAT(first_name,' ',last_name)) STORED NOT NULL);`)) - .to.equal("CREATE TABLE `contacts` (`id` INT KEY, `first_name` VARCHAR(50) NOT NULL, `last_name` VARCHAR(50) NOT NULL, `fullname` VARCHAR(101) NOT NULL CHARACTER SET LATIN1 COLLATE LATIN1_GENERAL_CS GENERATED ALWAYS AS (CONCAT(`first_name`, ' ', `last_name`)) STORED)"); + .to.equal("CREATE TABLE `contacts` (`id` INT KEY, `first_name` VARCHAR(50) NOT NULL, `last_name` VARCHAR(50) NOT NULL, `fullname` VARCHAR(101) NOT NULL CHARACTER SET latin1 COLLATE LATIN1_GENERAL_CS GENERATED ALWAYS AS (CONCAT(`first_name`, ' ', `last_name`)) STORED)"); expect(getParsedSql(`CREATE TABLE contacts (id INT KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, fullname varchar(101) GENERATED ALWAYS AS (CONCAT(first_name,' ',last_name)) VIRTUAL);`)) .to.equal("CREATE TABLE `contacts` (`id` INT KEY, `first_name` VARCHAR(50) NOT NULL, `last_name` VARCHAR(50) NOT NULL, `fullname` VARCHAR(101) GENERATED ALWAYS AS (CONCAT(`first_name`, ' ', `last_name`)) VIRTUAL)"); diff --git a/test/mysql-mariadb.spec.js b/test/mysql-mariadb.spec.js index f60a3647..a2a5fb42 100644 --- a/test/mysql-mariadb.spec.js +++ b/test/mysql-mariadb.spec.js @@ -551,7 +551,7 @@ describe('mysql', () => { title: 'index column length', sql: [ 'CREATE TABLE `Translation` (`id` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,`en-GB` text,PRIMARY KEY (`id`),KEY `Translation_en-GB_btree_idx` (`en-GB`(768))) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci', - 'CREATE TABLE `Translation` (`id` CHAR(36) NOT NULL CHARACTER SET ASCII COLLATE ASCII_BIN, `en-GB` TEXT, PRIMARY KEY (`id`), KEY Translation_en-GB_btree_idx (`en-GB` (768))) ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci', + 'CREATE TABLE `Translation` (`id` CHAR(36) NOT NULL CHARACTER SET ascii COLLATE ASCII_BIN, `en-GB` TEXT, PRIMARY KEY (`id`), KEY Translation_en-GB_btree_idx (`en-GB` (768))) ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci', ] }, { @@ -1040,6 +1040,22 @@ describe('mysql', () => { 'SELECT `year`, `country`, `product`, SUM(`profit`) AS `profit` FROM `sales` GROUP BY `year`, `country`, `product` WITH ROLLUP' ] }, + { + title: 'character set quoted ident', + sql: [ + `CREATE TABLE \`Table\` ( + TableID INTEGER PRIMARY KEY, + IsAbstract BOOLEAN, + HasOpenColumns BOOLEAN, + HasOpenRows BOOLEAN, + HasOpenSheets BOOLEAN, + IsNormalised BOOLEAN, + IsFlat BOOLEAN, + RowGUID VARCHAR(16) + ) CHARACTER SET 'UTF8';`, + 'CREATE TABLE `Table` (`TableID` INTEGER PRIMARY KEY, `IsAbstract` BOOLEAN, `HasOpenColumns` BOOLEAN, `HasOpenRows` BOOLEAN, `HasOpenSheets` BOOLEAN, `IsNormalised` BOOLEAN, `IsFlat` BOOLEAN, `RowGUID` VARCHAR(16)) CHARACTER SET \'UTF8\'' + ] + }, ] SQL_LIST.forEach(sqlInfo => { const { title, sql } = sqlInfo diff --git a/test/select.spec.js b/test/select.spec.js index 4989cc20..96f8076c 100644 --- a/test/select.spec.js +++ b/test/select.spec.js @@ -750,9 +750,9 @@ describe('select', () => { expect(getParsedSql(`select * from test where CONVERT(column using utf8)="test";`)) .to.equal('SELECT * FROM `test` WHERE CONVERT(`column` USING UTF8) = "test"') expect(getParsedSql(`SELECT CONVERT('test', CHAR CHARACTER SET utf8mb4);`)) - .to.equal("SELECT CONVERT('test', CHAR CHARACTER SET UTF8MB4)") + .to.equal("SELECT CONVERT('test', CHAR CHARACTER SET utf8mb4)") expect(getParsedSql(`SELECT CONVERT('test', CHAR(10) CHARACTER SET utf8mb4);`)) - .to.equal("SELECT CONVERT('test', CHAR(10) CHARACTER SET UTF8MB4)") + .to.equal("SELECT CONVERT('test', CHAR(10) CHARACTER SET utf8mb4)") expect(getParsedSql(`SELECT CONVERT('test' USING utf8mb4) COLLATE utf8mb4_bin;`)) .to.equal("SELECT CONVERT('test' USING UTF8MB4) COLLATE UTF8MB4_BIN") expect(getParsedSql(`select TYPE,taxpayer_Type,CONVERT(tax_Amount, DECIMAL(12,2)) AS tax_amount,CAST(tax_currency AS DECIMAL(12,2)) tax_currency from rs_order_tax where billno="{{billno}}" and Business_Type="order";`))