diff --git a/public/app/plugins/datasource/influxdb/influx_query.ts b/public/app/plugins/datasource/influxdb/influx_query.ts index 3ee9d703c54..a655705ffcb 100644 --- a/public/app/plugins/datasource/influxdb/influx_query.ts +++ b/public/app/plugins/datasource/influxdb/influx_query.ts @@ -146,7 +146,7 @@ export default class InfluxQuery { value = this.templateSrv.replace(value, this.scopedVars); } if (operator !== '>' && operator !== '<') { - value = "'" + value.replace(/\\/g, '\\\\') + "'"; + value = "'" + value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'") + "'"; } } else if (interpolate) { value = this.templateSrv.replace(value, this.scopedVars, 'regex'); diff --git a/public/app/plugins/datasource/influxdb/specs/influx_query.test.ts b/public/app/plugins/datasource/influxdb/specs/influx_query.test.ts index f8e65c21f2d..ad76ea5309c 100644 --- a/public/app/plugins/datasource/influxdb/specs/influx_query.test.ts +++ b/public/app/plugins/datasource/influxdb/specs/influx_query.test.ts @@ -139,6 +139,26 @@ describe('InfluxQuery', () => { }); }); + describe('field name with single quote should be escaped and', () => { + it('should generate correct query', () => { + const query = new InfluxQuery( + { + measurement: 'cpu', + groupBy: [{ type: 'time', params: ['auto'] }], + tags: [{ key: 'name', value: "Let's encrypt." }, { key: 'hostname', value: 'server2', condition: 'OR' }], + }, + templateSrv, + {} + ); + + const queryText = query.render(); + expect(queryText).toBe( + 'SELECT mean("value") FROM "cpu" WHERE ("name" = \'Let\\\'s encrypt.\' OR "hostname" = \'server2\') AND ' + + '$timeFilter GROUP BY time($__interval)' + ); + }); + }); + describe('query with value condition', () => { it('should not quote value', () => { const query = new InfluxQuery(