github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/query/expression_vm.h (about)

     1  //  Copyright (c) 2017-2018 Uber Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #ifndef QUERY_EXPRESSION_VM_H_
    16  #define QUERY_EXPRESSION_VM_H_
    17  #include <stddef.h>
    18  #include <stdint.h>
    19  
    20  // The expression VM is a stack based interpreter that evaluates expressions
    21  // (filter, dimension, pre-aggregate measure) on GPUs.
    22  // For simplicity each instruction is a 32-bit word using the following format:
    23  //   Bits masked by 0xff000000 defines the instruction itself.
    24  //   Bits masked by 0x0000ffff defines the payload of the instruction.
    25  //
    26  // A pair of value/null stack is used to process SQL expressions.
    27  // Each slot in the value stack always takes 4 bytes, regardless of the type,
    28  // while each slot in the null stack takes 1 byte.
    29  // Both stack grows up from lower address to higher address.
    30  enum ExprVMInst {
    31    // End of the instruction sequence, stops the expression VM.
    32    INST_EOF               = 0,
    33  
    34    // Invokes a function call with the top X parameters on the stack pair.
    35    // The last parameter is on top of the stack, while the first is the deepest
    36    // in the stack.
    37    // The call type is specified in the payload (masked by 0x0000ffff).
    38    // At the end of the call, the result is put on top of the stack pair.
    39    //
    40    // TODO(lucafuji): to support an argument with variable-length data
    41    // (e.g., geofence),
    42    // We need to add a third stack for storing offsets to the value stack,
    43    // and introduce new instructions that operate on the offset stack.
    44    INST_CALL              = 0x01000000,
    45  
    46    // Reads from an input column and pushes it onto the top of the stack pair.
    47    // The payload (masked by 0x0000ffff) defines index to the column to be read
    48    // from the global (query-wise) column array. Values are always stored using
    49    // 4 bytes regardless of their types for simplicity.
    50    INST_PUSH              = 0x02000000,
    51  
    52    // The following instructions push a constant onto the top of the stack pair.
    53    // To push a small integer that fits in a 16-bit word, simply put the integer
    54    // as the payload of INST_PUSH_CONST_LOW.
    55    // To push a big integer that does not fit, first split it to lower 16 bits
    56    // and higher 16 bits, then put the lower 16 bits as the payload of
    57    // INST_PUSH_CONST_LOW, then put the higher 16 bits as the payload of
    58    // INST_WRITE_CONST_HIGH. Note that INST_WRITE_CONST_HIGH writes the payload
    59    // to the higher 16 bits of the word on top of the value stack, without moving
    60    // the stack pointer.
    61    INST_PUSH_CONST_NULL   = 0x03000000,
    62    INST_PUSH_CONST_LOW    = 0x04000000,
    63    INST_WRITE_CONST_HIGH  = 0x05000000,
    64  
    65    // Skips the next X instructions when the top of the value stack is
    66    // zero/non-zero. X is specified in the payload (masked by 0x0000ffff).
    67    // The purpose of this instruction is to allow short-circuiting in logical
    68    // expresions, and to allow case-when-then-else-end (if-else) expression.
    69    INST_JZ                = 0x06000000,
    70    INST_JNZ               = 0x07000000,
    71  
    72    // Skips the next X instructions.
    73    // X is specified in the payload (masked by 0x0000ffff).
    74    // The purpose of this instruction is to allow case-when-then-else-end
    75    // (if-else) expression (jumping from the end of if block to end of else).
    76    INST_JMP               = 0x08000000
    77  };
    78  
    79  // ExprVMCall defines the call types of all operators and (non-aggregate)
    80  // functions. UDF functions also share the same call type space.
    81  enum ExprVMCall {
    82    // Unary OPs
    83    CALL_NEG               = 0x01,
    84    CALL_NEG_FLOAT         = 0x02,
    85    CALL_NOT               = 0x03,
    86    CALL_BITWISE_NOT       = 0x04,
    87    CALL_SIGNED_TO_FLOAT   = 0x05,
    88    CALL_UNSIGNED_TO_FLOAT = 0x06,
    89    CALL_FLOAT_TO_SIGNED   = 0x07,
    90    CALL_FLOAT_TO_UNSIGNED = 0x08,
    91  
    92    // Operators above this line do not need to modify the null stack.
    93    call_begin_null_ops    = 0x0d,
    94  
    95    CALL_IS_NULL           = 0x0e,
    96    CALL_IS_NOT_NULL       = 0x0f,
    97  
    98    // Binary OPs
    99    call_begin_binary_ops  = 0x10,
   100  
   101    CALL_IS                = 0x11,
   102    // In SQL expression: NULL AND FALSE = FALSE, NULL OR TRUE = TRUE...
   103    CALL_AND               = 0x12,
   104    CALL_OR                = 0x13,
   105  
   106    call_end_null_ops      = 0x14,
   107    // Operators below this line can simply run nulls[0] = nulls[0] && nulls[1] to
   108    // handle nulls. Note that the null stack stores validity.
   109  
   110    CALL_XOR               = 0x21,
   111    CALL_BITWISE_AND       = 0x22,
   112    CALL_BITWISE_OR        = 0x23,
   113    CALL_BITWISE_XOR       = 0x24,
   114    CALL_SHL               = 0x25,
   115    CALL_SHR               = 0x26,
   116    CALL_EQ                = 0x27,
   117    CALL_EQ_FLOAT          = 0x28,
   118    CALL_LT_SIGNED         = 0x29,
   119    CALL_LT_UNSIGNED       = 0x2a,
   120    CALL_LT_FLOAT          = 0x2b,
   121    CALL_LE_SIGNED         = 0x2c,
   122    CALL_LE_UNSIGNED       = 0x2d,
   123    CALL_LE_FLOAT          = 0x2e,
   124  
   125    CALL_ADD               = 0x31,
   126    CALL_ADD_FLOAT         = 0x32,
   127    CALL_SUB               = 0x33,
   128    CALL_SUB_FLOAT         = 0x34,
   129    CALL_MUL_SIGNED        = 0x35,
   130    CALL_MUL_UNSIGNED      = 0x36,
   131    CALL_MUL_FLOAT         = 0x37,
   132    CALL_DIV_SIGNED        = 0x38,
   133    CALL_DIV_UNSIGNED      = 0x39,
   134    CALL_DIV_FLOAT         = 0x3a,
   135    CALL_MOD_SIGNED        = 0x3b,
   136    CALL_MOD_UNSIGNED      = 0x3c,
   137    CALL_MOD_FLOAT         = 0x3d
   138  };
   139  #endif  // QUERY_EXPRESSION_VM_H_