Skip to content

Commit

Permalink
implement wrapping pretty printer
Browse files Browse the repository at this point in the history
  • Loading branch information
vadimkibana committed Aug 15, 2024
1 parent 74c9570 commit f71385e
Show file tree
Hide file tree
Showing 18 changed files with 2,240 additions and 545 deletions.
24 changes: 24 additions & 0 deletions packages/kbn-esql-ast/src/__tests__/ast_parser.literal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,28 @@ describe('literal expression', () => {
value: 1,
});
});

it('decimals vs integers', () => {
const text = 'ROW a(1.0, 1)';
const { ast } = parse(text);

expect(ast[0]).toMatchObject({
type: 'command',
args: [
{
type: 'function',
args: [
{
type: 'literal',
literalType: 'decimal',
},
{
type: 'literal',
literalType: 'integer',
},
],
},
],
});
});
});
26 changes: 26 additions & 0 deletions packages/kbn-esql-ast/src/__tests__/ast_parser.rename.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { getAstAndSyntaxErrors as parse } from '../ast_parser';

describe('RENAME', () => {
/**
* Enable this test once RENAME commands are fixed:
* https://github.com/elastic/kibana/discussions/182393#discussioncomment-10313313
*/
it.skip('example from documentation', () => {
const text = `
FROM kibana_sample_data_logs
| RENAME total_visits as \`Unique Visits (Total)\`,
`;
const { ast } = parse(text);

// eslint-disable-next-line no-console
console.log(JSON.stringify(ast, null, 2));
});
});
19 changes: 19 additions & 0 deletions packages/kbn-esql-ast/src/ast/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

/**
* The group name of a binary expression. Groups are ordered by precedence.
*/
export enum BinaryExpressionGroup {
unknown = 0,
additive = 10,
multiplicative = 20,
assignment = 30,
comparison = 40,
regex = 50,
}
69 changes: 69 additions & 0 deletions packages/kbn-esql-ast/src/ast/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { ESQLAstNode, ESQLBinaryExpression, ESQLFunction } from '../types';
import { BinaryExpressionGroup } from './constants';

export const isFunctionExpression = (node: unknown): node is ESQLFunction =>
!!node && typeof node === 'object' && !Array.isArray(node) && (node as any).type === 'function';

/**
* Returns true if the given node is a binary expression, i.e. an operator
* surrounded by two operands:
*
* ```
* 1 + 1
* column LIKE "foo"
* foo = "bar"
* ```
*
* @param node Any ES|QL AST node.
*/
export const isBinaryExpression = (node: unknown): node is ESQLBinaryExpression =>
isFunctionExpression(node) && node.subtype === 'binary-expression';

/**
* Returns the group of a binary expression:
*
* - `additive`: `+`, `-`
* - `multiplicative`: `*`, `/`, `%`
* - `assignment`: `=`
* - `comparison`: `==`, `=~`, `!=`, `<`, `<=`, `>`, `>=`
* - `regex`: `like`, `not_like`, `rlike`, `not_rlike`
* @param node Any ES|QL AST node.
* @returns Binary expression group or undefined if the node is not a binary expression.
*/
export const binaryExpressionGroup = (node: ESQLAstNode): BinaryExpressionGroup => {
if (isBinaryExpression(node)) {
switch (node.name) {
case '+':
case '-':
return BinaryExpressionGroup.additive;
case '*':
case '/':
case '%':
return BinaryExpressionGroup.multiplicative;
case '=':
return BinaryExpressionGroup.assignment;
case '==':
case '=~':
case '!=':
case '<':
case '<=':
case '>':
case '>=':
return BinaryExpressionGroup.comparison;
case 'like':
case 'not_like':
case 'rlike':
case 'not_rlike':
return BinaryExpressionGroup.regex;
}
}
return BinaryExpressionGroup.unknown;
};
23 changes: 23 additions & 0 deletions packages/kbn-esql-ast/src/pretty_print/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Pretty-printing

*Pretty-printing* is the process of converting an ES|QL AST into a
human-readable string. This is useful for debugging or for displaying
the AST to the user.

This module provides a number of pretty-printing options.


## `BasicPrettyPrinter`

The `BasicPrettyPrinter` class provides the most basic pretty-printing&mdash;it
prints a query to a single line. Or it can print a query with each command on
a separate line, with the ability to customize the indentation before the pipe
character.

It can also print a single command to a single line; or an expression to a
single line.

- `BasicPrettyPrinter.print()` &mdash; prints query to a single line.
- `BasicPrettyPrinter.multiline()` &mdash; prints a query to multiple lines.
- `BasicPrettyPrinter.command()` &mdash; prints a command to a single line.
- `BasicPrettyPrinter.expression()` &mdash; prints an expression to a single line.
Loading

0 comments on commit f71385e

Please sign in to comment.