diff --git a/pegjs/mariadb.pegjs b/pegjs/mariadb.pegjs index 3fe14f2b..25e8a089 100644 --- a/pegjs/mariadb.pegjs +++ b/pegjs/mariadb.pegjs @@ -3963,6 +3963,14 @@ data_type / blob_type / geometry_type +data_type_size + = LPAREN __ l:[0-9]+ __ RPAREN __ s:numeric_type_suffix? { + return { + length: parseInt(l.join(''), 10), + parentheses: true, + suffix: s, + }; + } boolean_type = 'boolean'i { return { dataType: 'BOOLEAN' }; } @@ -3970,18 +3978,20 @@ blob_type = b:('blob'i / 'tinyblob'i / 'mediumblob'i / 'longblob'i) { return { dataType: b.toUpperCase() }; } binary_type - = t:(KW_BINARY / KW_VARBINARY) __ LPAREN __ l:[0-9]+ __ RPAREN { - return { dataType: t, length: parseInt(l.join(''), 10) }; + = t:(KW_BINARY / KW_VARBINARY) __ num:data_type_size? { + return { dataType: t, ...(num || {}) } } - / t:KW_BINARY { return { dataType: t }; } - character_string_type - = t:(KW_CHAR / KW_VARCHAR) __ LPAREN __ l:[0-9]+ __ RPAREN __ s:('ARRAY'i)? { - return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true, suffix: s && ['ARRAY'] }; + = t:(KW_CHAR / KW_VARCHAR) num:(__ LPAREN __ [0-9]+ __ RPAREN __ ('ARRAY'i)?)? { + const result = { dataType: t } + if (num) { + result.length = parseInt(num[3].join(''), 10) + result.parentheses = true + result.suffix = num[7] && ['ARRAY'] + } + return result } - / t:KW_CHAR { return { dataType: t }; } - / t:KW_VARCHAR { return { dataType: t }; } numeric_type_suffix = un: KW_UNSIGNED? __ ze: KW_ZEROFILL? { @@ -3996,8 +4006,15 @@ numeric_type / t:(KW_NUMERIC / KW_DECIMAL / KW_INT / KW_INTEGER / KW_SMALLINT / KW_MEDIUMINT / KW_TINYINT / KW_BIGINT / KW_FLOAT / KW_DOUBLE) __ s:numeric_type_suffix? __{ return { dataType: t, suffix: s }; } datetime_type - = t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP / KW_YEAR) __ LPAREN __ l:[0-6] __ RPAREN __ s:numeric_type_suffix? { return { dataType: t, length: parseInt(l, 10), parentheses: true }; } - / t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP / KW_YEAR) { return { dataType: t }; } + = t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP / KW_YEAR) num:(__ LPAREN __ [0-6] __ RPAREN __ numeric_type_suffix?)? { + const result = { dataType: t } + if (num) { + result.length = parseInt(num[3], 10) + result.parentheses = true + result.suffix = num[7] + } + return result + } enum_type = t:(KW_ENUM / KW_SET) __ e:value_item { @@ -4007,11 +4024,14 @@ enum_type expr: e } } + json_type = t:KW_JSON { return { dataType: t }; } text_type - = t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) { return { dataType: t }} + = t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) num:data_type_size? { + return { dataType: t, ...(num || {}) } + } geometry_type = t:(KW_GEOMETRY / KW_POINT / KW_LINESTRING / KW_POLYGON / KW_MULTIPOINT / KW_MULTILINESTRING / KW_MULTIPOLYGON / KW_GEOMETRYCOLLECTION ) { return { dataType: t }} diff --git a/pegjs/mysql.pegjs b/pegjs/mysql.pegjs index 98d8f7cf..7227a553 100644 --- a/pegjs/mysql.pegjs +++ b/pegjs/mysql.pegjs @@ -4284,6 +4284,14 @@ data_type / blob_type / geometry_type +data_type_size + = LPAREN __ l:[0-9]+ __ RPAREN __ s:numeric_type_suffix? { + return { + length: parseInt(l.join(''), 10), + parentheses: true, + suffix: s, + }; + } boolean_type = 'boolean'i { return { dataType: 'BOOLEAN' }; } @@ -4291,17 +4299,20 @@ blob_type = b:('blob'i / 'tinyblob'i / 'mediumblob'i / 'longblob'i) { return { dataType: b.toUpperCase() }; } binary_type - = t:(KW_BINARY / KW_VARBINARY) __ LPAREN __ l:[0-9]+ __ RPAREN { - return { dataType: t, length: parseInt(l.join(''), 10) }; + = t:(KW_BINARY / KW_VARBINARY) __ num:data_type_size? { + return { dataType: t, ...(num || {}) } } - / t:KW_BINARY { return { dataType: t }; } character_string_type - = t:(KW_CHAR / KW_VARCHAR) __ LPAREN __ l:[0-9]+ __ RPAREN __ s:('ARRAY'i)? { - return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true, suffix: s && ['ARRAY'] }; + = t:(KW_CHAR / KW_VARCHAR) num:(__ LPAREN __ [0-9]+ __ RPAREN __ ('ARRAY'i)?)? { + const result = { dataType: t } + if (num) { + result.length = parseInt(num[3].join(''), 10) + result.parentheses = true + result.suffix = num[7] && ['ARRAY'] + } + return result } - / t:KW_CHAR { return { dataType: t }; } - / t:KW_VARCHAR { return { dataType: t }; } numeric_type_suffix = un: KW_UNSIGNED? __ ze: KW_ZEROFILL? { @@ -4317,8 +4328,15 @@ numeric_type datetime_type - = t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP / KW_YEAR) __ LPAREN __ l:[0-6] __ RPAREN __ s:numeric_type_suffix? { return { dataType: t, length: parseInt(l, 10), parentheses: true }; } - / t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP / KW_YEAR) { return { dataType: t }; } + = t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP / KW_YEAR) num:(__ LPAREN __ [0-6] __ RPAREN __ numeric_type_suffix?)? { + const result = { dataType: t } + if (num) { + result.length = parseInt(num[3], 10) + result.parentheses = true + result.suffix = num[7] + } + return result + } enum_type = t:(KW_ENUM / KW_SET) __ e:value_item { @@ -4333,7 +4351,9 @@ json_type = t:KW_JSON { return { dataType: t }; } text_type - = t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) { return { dataType: t }} + = t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) num:data_type_size? { + return { dataType: t, ...(num || {}) } + } geometry_type = t:(KW_GEOMETRY / KW_POINT / KW_LINESTRING / KW_POLYGON / KW_MULTIPOINT / KW_MULTILINESTRING / KW_MULTIPOLYGON / KW_GEOMETRYCOLLECTION ) { return { dataType: t }} diff --git a/pegjs/postgresql.pegjs b/pegjs/postgresql.pegjs index cd2f3767..59440671 100644 --- a/pegjs/postgresql.pegjs +++ b/pegjs/postgresql.pegjs @@ -5729,11 +5729,15 @@ character_varying return 'CHARACTER VARYING' } character_string_type - = t:(KW_CHAR / KW_VARCHAR / character_varying) __ LPAREN __ l:[0-9]+ __ RPAREN { + = t:(KW_CHAR / KW_VARCHAR / character_varying) num:(__ LPAREN __ [0-9]+ __ RPAREN)? { // => data_type - return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true }; + const result = { dataType: t } + if (num) { + result.length = parseInt(num[3].join(''), 10) + result.parentheses = true + } + return result } - / t:(KW_CHAR / character_varying / KW_VARCHAR) { /* => data_type */ return { dataType: t }; } numeric_type_suffix = un: KW_UNSIGNED? __ ze: KW_ZEROFILL? { @@ -5758,13 +5762,27 @@ timezone } time_type - = t:(KW_TIME / KW_TIMESTAMP / KW_TIMESTAMPTZ) __ LPAREN __ l:[0-9]+ __ RPAREN __ tz:timezone? { /* => data_type */ return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true, suffix: tz }; } - / t:(KW_TIME / KW_TIMESTAMP) __ tz:timezone? { /* => data_type */ return { dataType: t, suffix: tz }; } - / t:KW_TIMESTAMPTZ { /* => data_type */ return { dataType: t }; } + = t:(KW_TIME / KW_TIMESTAMP / KW_TIMESTAMPTZ) num:(__ LPAREN __ [0-9]+ __ RPAREN )? __ tz:timezone? { + /* => data_type */ + const result = { dataType: t } + if (num) { + result.length = parseInt(num[3].join(''), 10) + result.parentheses = true + } + if (tz) result.suffix = tz + return result + } datetime_type - = t:(KW_DATE / KW_DATETIME) __ LPAREN __ l:[0-9]+ __ RPAREN { /* => data_type */ return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true }; } - / t:(KW_DATE / KW_DATETIME) { /* => data_type */ return { dataType: t }; } + = t:(KW_DATE / KW_DATETIME) num:(__ LPAREN __ [0-9]+ __ RPAREN)? { + /* => data_type */ + const result = { dataType: t } + if (num) { + result.length = parseInt(num[3].join(''), 10) + result.parentheses = true + } + return result + } / time_type enum_type @@ -5787,8 +5805,10 @@ serial_interval_type = t:(KW_SERIAL / KW_INTERVAL) { /* => data_type */ return { dataType: t }; } text_type - = t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) LBRAKE __ RBRAKE { /* => data_type */ return { dataType: `${t}[]` }} - / t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) { /* => data_type */ return { dataType: t }} + = t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) s:(LBRAKE __ RBRAKE)? { + /* => data_type */ + return { dataType: `${t}${s ? '[]' : ''}` } + } uuid_type = t:KW_UUID {/* => data_type */ return { dataType: t }} diff --git a/test/mysql-mariadb.spec.js b/test/mysql-mariadb.spec.js index 866f7f25..3c855204 100644 --- a/test/mysql-mariadb.spec.js +++ b/test/mysql-mariadb.spec.js @@ -1101,6 +1101,13 @@ describe('mysql', () => { "SELECT DISTINCT `pv`.`text` AS `product_page_text`, `pv`.`lp_url`, `pp`.`short_label` AS `product_item_text`, `pp`.`id` AS `promoid`, `pv`.`id` AS `visibility_id`, `pp`.`tnc` FROM (`product_promotion` AS `pp`) INNER JOIN `promotion_visibility` AS `pv` ON `pv`.`promotion_id` = `pp`.`id` WHERE `pv`.`property` = 'app_product_page_text' AND `pp`.`start_date` < 1724305037 AND `pp`.`end_date` > 1724305037 AND `pv`.`is_active` = 1 AND `pp`.`is_active` = 1 AND `pp`.`id` IN ('5725,8560') ORDER BY `pp`.`priority` DESC", ] }, + { + title: 'text data type with length', + sql: [ + 'CREATE TABLE `ys_map_info` (`detail` TEXT(65535));', + 'CREATE TABLE `ys_map_info` (`detail` TEXT(65535))' + ] + }, ] SQL_LIST.forEach(sqlInfo => { const { title, sql } = sqlInfo