Current section
Files
Jump to
Current section
Files
caffeine_query_language
README.md
README.md
# Caffeine Query LanguageCQL is a very simple arithmetic language that is used to express SLIs. We expect it to grow over time, but for it to never be Turing complete.The following operators are supported:- `/` : Division- `*` : Multiplication- `+` : Addition- `-` : Subtraction- `(` and `)` : Parentheses### Grammar:```CQL_QUERY ::= EXPEXP ::= ADDADD ::= MUL (('+' | '-') MUL)*MUL ::= PRIMARY (('*' | '/') PRIMARY)*PRIMARY ::= WORD | '(' EXP ')'WORD ::= [A-Za-z_]+```### Query PrimitivesWhile I've already placed a fairly rigid constraint on CQL by saying it's never going to be Turing complete, I'll further constrain by saying it must map to a _query primitive_. A query primitive is:```A query form or structure that comes shipped with caffeine; a sort of standard library for queries. ```For example, the first primitive we will support is `good and valid over total`. We _map_ to this by ensuring our query reduces to a numerator over a denominator.***## Phase to Phase**(1): Parsing**In this step, we parse the CQL query into its parse tree.Input:```(A + B) / C```Output:```gleamlet query = CQL_QUERY └─ EXP └─ ADD └─ MUL ├─ PRIMARY │ └─ "(" EXP ")" │ └─ ADD │ ├─ MUL │ │ └─ PRIMARY │ │ └─ WORD("A") │ ├─ "+" │ └─ MUL │ └─ PRIMARY │ └─ WORD("B") ├─ "/" └─ PRIMARY └─ WORD("C")UnresolvedQueryTemplateType( ... query: query ...)```**(2): Linking**Linking in the caffeine compiler is mostly about resolving references between structures from different files. Since the query is all in one file, it isn't modified at all in this step (it's just moved from one object to another).Input:```gleamUnresolvedQueryTemplateType( ... query: query ...)```Output:```gleamQueryTemplateType( ... query: query ...)```**(3): Semantic Analysis**Here we perform a series of checks including, but not limited to:* ensuring the types of query values are compatibleWe do not modify the parse tree. We simply traverse to ensure its validity.Input:```gleamQueryTemplateType( ... query: query ...)```Output:```gleamQueryTemplateType( ... query: query ...)```**(4): Resolution**In this step, we attempt to reduce our CQL query to a query primitive. Then we resolve the query template variables. The final result is fairly close to what the backend generator will useInput:```gleamQueryTemplateType( ... query: query ...)```Output:```gleamQueryTemplateType( ... query: QUERY_PRIMITIVE( numerator = "(SOME_QUERY_A + SOME_QUERY_B)" denominator = "SOME_QUERY_C"" ...)```**(5): Generation**Given a query primitive, we generator reliability artifact(s).Input:```gleamQueryTemplateType( ... query: QUERY_PRIMITIVE( numerator = "(SOME_QUERY_A + SOME_QUERY_B)" denominator = "SOME_QUERY_C"" ...```Output:```terraform...query { numerator: "(SOME_QUERY_A + SOME_QUERY_B)" denominator: "SOME_QUERY_C"}```***## A Full Example### Specification**basic_types.yaml**```basic_types: - attribute_name: some_value attribute_type: String```**query_template_types.yaml**```query_template_types: - name: "valid_over_total" query: "numerator / denominator" specification_of_query_templates: ["numerator", "denominator"]```**sli_types.yaml**```types: - name: success_rate query_template_type: valid_over_total typed_instatiation_of_query_templates: numerator: "sum:hits_and_errors{status:success env:$$some_value$$}" denominator: "sum:hits_and_errors{env:$$some_value$$}" specification_of_query_templatized_variables: - some_value```**services.yaml**```services: - name: reliable_service sli_types: - success_rate```### Instantiation**company/platform/reliable_service.yaml**```slos: - sli_type: "success_rate" typed_instatiation_of_query_templatized_variables: "some_value": "foobar" threshold: 99.5 window_in_days: 30```***