meta_query.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. export class MysqlMetaQuery {
  2. constructor(private target, private queryModel) {}
  3. getOperators(datatype: string) {
  4. switch (datatype) {
  5. case 'double':
  6. case 'float': {
  7. return ['=', '!=', '<', '<=', '>', '>='];
  8. }
  9. case 'text':
  10. case 'tinytext':
  11. case 'mediumtext':
  12. case 'longtext':
  13. case 'varchar':
  14. case 'char': {
  15. return ['=', '!=', '<', '<=', '>', '>=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE'];
  16. }
  17. default: {
  18. return ['=', '!=', '<', '<=', '>', '>=', 'IN', 'NOT IN'];
  19. }
  20. }
  21. }
  22. // quote identifier as literal to use in metadata queries
  23. quoteIdentAsLiteral(value) {
  24. return this.queryModel.quoteLiteral(this.queryModel.unquoteIdentifier(value));
  25. }
  26. findMetricTable() {
  27. // query that returns first table found that has a timestamp(tz) column and a float column
  28. const query = `
  29. SELECT
  30. table_name as table_name,
  31. ( SELECT
  32. column_name as column_name
  33. FROM information_schema.columns c
  34. WHERE
  35. c.table_schema = t.table_schema AND
  36. c.table_name = t.table_name AND
  37. c.data_type IN ('timestamp', 'datetime')
  38. ORDER BY ordinal_position LIMIT 1
  39. ) AS time_column,
  40. ( SELECT
  41. column_name AS column_name
  42. FROM information_schema.columns c
  43. WHERE
  44. c.table_schema = t.table_schema AND
  45. c.table_name = t.table_name AND
  46. c.data_type IN('float', 'int', 'bigint')
  47. ORDER BY ordinal_position LIMIT 1
  48. ) AS value_column
  49. FROM information_schema.tables t
  50. WHERE
  51. EXISTS
  52. ( SELECT 1
  53. FROM information_schema.columns c
  54. WHERE
  55. c.table_schema = t.table_schema AND
  56. c.table_name = t.table_name AND
  57. c.data_type IN ('timestamp', 'datetime')
  58. ) AND
  59. EXISTS
  60. ( SELECT 1
  61. FROM information_schema.columns c
  62. WHERE
  63. c.table_schema = t.table_schema AND
  64. c.table_name = t.table_name AND
  65. c.data_type IN('float', 'int', 'bigint')
  66. )
  67. LIMIT 1
  68. ;`;
  69. return query;
  70. }
  71. buildTableConstraint(table: string) {
  72. let query = '';
  73. // check for schema qualified table
  74. if (table.includes('.')) {
  75. const parts = table.split('.');
  76. query = 'table_schema = ' + this.quoteIdentAsLiteral(parts[0]);
  77. query += ' AND table_name = ' + this.quoteIdentAsLiteral(parts[1]);
  78. return query;
  79. } else {
  80. query = 'table_schema = database() AND table_name = ' + this.quoteIdentAsLiteral(table);
  81. return query;
  82. }
  83. }
  84. buildTableQuery() {
  85. return 'SELECT table_name FROM information_schema.tables WHERE table_schema = database() ORDER BY table_name';
  86. }
  87. buildColumnQuery(type?: string) {
  88. let query = 'SELECT column_name FROM information_schema.columns WHERE ';
  89. query += this.buildTableConstraint(this.target.table);
  90. switch (type) {
  91. case 'time': {
  92. query += " AND data_type IN ('timestamp','datetime','bigint','int','double','float')";
  93. break;
  94. }
  95. case 'metric': {
  96. query += " AND data_type IN ('text','tinytext','mediumtext','longtext','varchar','char')";
  97. break;
  98. }
  99. case 'value': {
  100. query += " AND data_type IN ('bigint','int','smallint','mediumint','tinyint','double','decimal','float')";
  101. query += ' AND column_name <> ' + this.quoteIdentAsLiteral(this.target.timeColumn);
  102. break;
  103. }
  104. case 'group': {
  105. query += " AND data_type IN ('text','tinytext','mediumtext','longtext','varchar','char')";
  106. break;
  107. }
  108. }
  109. query += ' ORDER BY column_name';
  110. return query;
  111. }
  112. buildValueQuery(column: string) {
  113. let query = 'SELECT DISTINCT QUOTE(' + column + ')';
  114. query += ' FROM ' + this.target.table;
  115. query += ' WHERE $__timeFilter(' + this.target.timeColumn + ')';
  116. query += ' ORDER BY 1 LIMIT 100';
  117. return query;
  118. }
  119. buildDatatypeQuery(column: string) {
  120. let query = `
  121. SELECT data_type
  122. FROM information_schema.columns
  123. WHERE `;
  124. query += ' table_name = ' + this.quoteIdentAsLiteral(this.target.table);
  125. query += ' AND column_name = ' + this.quoteIdentAsLiteral(column);
  126. return query;
  127. }
  128. }