static void cg_binary_compare()

in sources/cg_c.c [993:1068]


static void cg_binary_compare(ast_node *ast, CSTR op, charbuf *is_null, charbuf *value, int32_t pri, int32_t pri_new) {
  sem_t sem_type_result = ast->sem->sem_type;
  sem_t sem_type_left = ast->left->sem->sem_type;
  sem_t sem_type_right = ast->right->sem->sem_type;

  bool_t is_text_op = is_text(sem_type_left) && is_text(sem_type_right);
  bool_t is_blob_op = is_blob(sem_type_left) && is_blob(sem_type_right);

  if (is_blob_op) {
    // we want to make sure blob is only supported for certain operation
    // even though we already have the semantic analysis for this.
    Invariant(is_ast_eq(ast) || is_ast_ne(ast));
  }

  if (!is_text_op && !is_blob_op) {
   // for numeric, the usual binary processing works
   cg_binary(ast, op, is_null, value, pri, pri_new);
   return;
  }

  // Both sides are text/blob or null; already verified compatible in semantic phase.

  CHARBUF_OPEN(comparison);

  if (needs_paren(ast, pri_new, pri)) {
    bprintf(&comparison, "(");
  }

  ast_node *l = ast->left;
  ast_node *r = ast->right;

  CG_RESERVE_RESULT_VAR(ast, sem_type_result);
  CG_PUSH_EVAL(l, pri_new);
  CG_PUSH_EVAL(r, pri_new);

  if (is_ast_like(ast)) {
    // like not allowed semantically for blob type
    Invariant(!is_blob_op);
    bprintf(&comparison, "%s(%s, %s) == 0", rt->cql_string_like, l_value.ptr, r_value.ptr);
  }
  else if (is_ast_not_like(ast)) {
    // like not allowed semantically for blob type
    Invariant(!is_blob_op);
    bprintf(&comparison, "%s(%s, %s) != 0", rt->cql_string_like, l_value.ptr, r_value.ptr);
  }
  else if (is_blob_op) {
    bool_t logical_not = is_ast_ne(ast) || is_ast_is_not(ast);
    if (logical_not) {
      bprintf(&comparison, "%s", "!");
    }
    bprintf(&comparison, "%s(%s, %s)", rt->cql_blob_equal, l_value.ptr, r_value.ptr);
  }
  else {
    // otherwise other string comparisons
    bprintf(&comparison, "%s(%s, %s) %s 0", rt->cql_string_compare, l_value.ptr, r_value.ptr, op);
  }

  if (needs_paren(ast, pri_new, pri)) {
    bprintf(&comparison, ")");
  }

  if (is_not_nullable(sem_type_left) && is_not_nullable(sem_type_right)) {
    bprintf(value, "%s", comparison.ptr);
    bprintf(is_null, "0");
  }
  else {
    CG_USE_RESULT_VAR();
    cg_combine_nullables(cg_main_output, result_var.ptr, l_is_null.ptr, r_is_null.ptr, comparison.ptr);
  }

  CG_POP_EVAL(r);
  CG_POP_EVAL(l);
  CG_CLEANUP_RESULT_VAR();

  CHARBUF_CLOSE(comparison);
}