static void __add_join (Psh *holder) { MidgardCRCoreQueryExecutor *executor = MIDGARD_CR_CORE_QUERY_EXECUTOR (holder->executor); GdaSqlStatement *sql_stm = executor->priv->stmt; GdaSqlStatementSelect *select = (GdaSqlStatementSelect *) sql_stm->contents; GdaSqlSelectFrom *from = select->from; GdaSqlSelectJoin *join = gda_sql_select_join_new (GDA_SQL_ANY_PART (from)); join->type = GDA_SQL_SELECT_JOIN_LEFT; GdaSqlExpr *expr = gda_sql_expr_new (GDA_SQL_ANY_PART (join)); expr->value = gda_value_new (G_TYPE_STRING); g_value_take_string (expr->value, g_strdup_printf ("%s.%s = %s.%s", holder->table_alias, holder->colname, holder->target_table_alias, holder->target_colname)); join->expr = expr; join->position = ++executor->priv->joinid; gda_sql_select_from_take_new_join (from , join); GdaSqlSelectTarget *s_target = gda_sql_select_target_new (GDA_SQL_ANY_PART (from)); s_target->table_name = g_strdup (holder->target_table); s_target->as = g_strdup (holder->target_table_alias); gda_sql_select_from_take_new_target (from, s_target); /* Set target expression */ GdaSqlExpr *texpr = gda_sql_expr_new (GDA_SQL_ANY_PART (s_target)); GValue *tval = g_new0 (GValue, 1); g_value_init (tval, G_TYPE_STRING); g_value_set_string (tval, s_target->table_name); texpr->value = tval; s_target->expr = texpr; }
gboolean __query_select_add_joins (MidgardQuerySelect *self, GdaSqlOperation *operation, GError **error) { __add_implicit_workspace_join (self, operation); if (!MIDGARD_QUERY_EXECUTOR (self)->priv->joins) return TRUE; GSList *l = NULL; MidgardQueryExecutor *executor = MIDGARD_QUERY_EXECUTOR (self); GdaSqlStatement *sql_stm = executor->priv->stmt; GdaSqlStatementSelect *select = (GdaSqlStatementSelect *) sql_stm->contents; GdaSqlSelectFrom *from = select->from; GdaSqlSelectJoin *join; for (l = MIDGARD_QUERY_EXECUTOR (self)->priv->joins; l != NULL; l = l->next) { qsj *_sj = (qsj*) l->data; join = gda_sql_select_join_new (GDA_SQL_ANY_PART (from)); join->type = _sj->join_type; MidgardQueryStorage *left_storage = _sj->left_property->priv->storage; MidgardQueryStorage *right_storage = _sj->right_property->priv->storage; GError *err = NULL; GValue lval = {0, }; midgard_query_holder_get_value (MIDGARD_QUERY_HOLDER (_sj->left_property), &lval); gchar *left_table_field = midgard_core_query_compute_constraint_property (executor, left_storage, g_value_get_string (&lval), &err); if (err) { g_propagate_error (error, err); g_free (left_table_field); } GValue rval = {0, }; midgard_query_holder_get_value (MIDGARD_QUERY_HOLDER (_sj->right_property), &rval); gchar *right_table_field = midgard_core_query_compute_constraint_property (executor, right_storage, g_value_get_string (&rval), &err); if (err) { g_propagate_error (error, err); g_free (right_table_field); } GdaSqlExpr *expr = gda_sql_expr_new (GDA_SQL_ANY_PART (join)); expr->value = gda_value_new (G_TYPE_STRING); g_value_take_string (expr->value, g_strdup_printf ("%s = %s", left_table_field, right_table_field)); join->expr = expr; join->position = ++executor->priv->joinid; /* Add right storage to targets */ MQE_SET_TABLE_ALIAS (executor, right_storage); gda_sql_select_from_take_new_join (from , join); GdaSqlSelectTarget *s_target = gda_sql_select_target_new (GDA_SQL_ANY_PART (from)); s_target->table_name = g_strdup (right_storage->priv->table); s_target->as = g_strdup (right_storage->priv->table_alias); gda_sql_select_from_take_new_target (from, s_target); // Set target expression GdaSqlExpr *texpr = gda_sql_expr_new (GDA_SQL_ANY_PART (s_target)); GValue *tval = g_new0 (GValue, 1); g_value_init (tval, G_TYPE_STRING); g_value_set_string (tval, right_storage->priv->table); texpr->value = tval; s_target->expr = texpr; } return TRUE; }
static void __add_implicit_workspace_join (MidgardQuerySelect *self, GdaSqlOperation *operation) { g_return_if_fail (self != NULL); MidgardDBObjectClass *klass = MIDGARD_QUERY_EXECUTOR (self)->priv->storage->priv->klass; if (!g_type_is_a (G_OBJECT_CLASS_TYPE (klass), MIDGARD_TYPE_OBJECT)) return; MidgardConnection *mgd = MIDGARD_QUERY_EXECUTOR (self)->priv->mgd; /* Do not take worskpace into account if if it's disabled * or enabled and none set */ if (!MGD_CNC_USES_WORKSPACE (mgd)) return; if (!MGD_CNC_HAS_WORKSPACE (mgd)) return; gboolean bool_is_int = MIDGARD_QUERY_EXECUTOR (self)->priv->bool_is_int; guint ws_id = MGD_CNC_WORKSPACE_ID (mgd); MidgardQueryExecutor *executor = MIDGARD_QUERY_EXECUTOR (self); GdaSqlStatement *sql_stm = executor->priv->stmt; GdaSqlStatementSelect *select = (GdaSqlStatementSelect *) sql_stm->contents; GdaSqlSelectFrom *from = select->from; GdaSqlSelectJoin *join; const gchar *klass_table = MGD_DBCLASS_TABLENAME (klass); gchar *left_table = executor->priv->table_alias; //gchar *right_table = g_strdup_printf ("t%d", ++executor->priv->tableid); gchar *right_table = g_strdup ("midgard_ws_tmp_table"); join = gda_sql_select_join_new (GDA_SQL_ANY_PART (from)); join->type = GDA_SQL_SELECT_JOIN_INNER; GdaSqlExpr *expr = gda_sql_expr_new (GDA_SQL_ANY_PART (join)); expr->value = gda_value_new (G_TYPE_STRING); g_value_take_string (expr->value, g_strdup_printf ("%s.%s = %s.%s", left_table, MGD_WORKSPACE_ID_FIELD, right_table, MGD_WORKSPACE_ID_FIELD)); join->expr = expr; join->position = ++executor->priv->joinid; MidgardConfig *config = mgd->priv->config; const gchar *sql_part_bool_func_start = ""; const gchar *sql_part_bool_func_end = ""; const gchar *deleted_field = midgard_core_object_get_deleted_field (klass); GString *table = g_string_new ("(SELECT DISTINCT MAX"); if (config->priv->dbtype == MIDGARD_DB_TYPE_POSTGRES && deleted_field) { sql_part_bool_func_start = " bool_or("; sql_part_bool_func_end = ") AS metadata_deleted"; } g_string_append_printf (table, "(%s) AS %s, %s %s%s%s%s FROM %s WHERE %s IN (0,", MGD_WORKSPACE_ID_FIELD, MGD_WORKSPACE_ID_FIELD, MGD_WORKSPACE_OID_FIELD, deleted_field ? "," : "", sql_part_bool_func_start, deleted_field ? deleted_field : "", sql_part_bool_func_end, klass_table, MGD_WORKSPACE_ID_FIELD); const MidgardWorkspaceStorage *ws = midgard_connection_get_workspace (mgd); GSList *list = MIDGARD_WORKSPACE_STORAGE_GET_INTERFACE (ws)->priv->list_ids (mgd, MIDGARD_WORKSPACE_STORAGE (ws)); GSList *l = NULL; guint i = 0; guint id; for (l = list; l != NULL; l = l->next, i++) { GValue *id_val = (GValue *) l->data; if (G_VALUE_HOLDS_UINT (id_val)) id = g_value_get_uint (id_val); else id = (guint) g_value_get_int (id_val); g_string_append_printf (table, "%s%d", i > 0 ? "," : "", id); } if (!list) g_string_append (table, "0"); g_string_append (table, ") "); if (deleted_field) g_string_append_printf (table, "AND %s = %s ", deleted_field, __BOOL_VALUE (bool_is_int)); g_string_append_printf (table, "GROUP BY %s)", MGD_WORKSPACE_OID_FIELD); g_slist_free (list); gda_sql_select_from_take_new_join (from , join); GdaSqlSelectTarget *s_target = gda_sql_select_target_new (GDA_SQL_ANY_PART (from)); s_target->table_name = g_string_free (table, FALSE); s_target->as = right_table; gda_sql_select_from_take_new_target (from, s_target); /* MIDGARD_QUERY_EXECUTOR (self)->priv->include_deleted_targets = g_slist_append (MIDGARD_QUERY_EXECUTOR (self)->priv->include_deleted_targets, s_target); */ GdaSqlExpr *texpr = gda_sql_expr_new (GDA_SQL_ANY_PART (s_target)); GValue *tval = g_new0 (GValue, 1); g_value_init (tval, G_TYPE_STRING); g_value_set_string (tval, g_strdup (s_target->table_name)); texpr->value = tval; s_target->expr = texpr; /* Add workspace object id constraint */ GdaSqlExpr *ws_expr = gda_sql_expr_new (GDA_SQL_ANY_PART (operation)); ws_expr->value = gda_value_new (G_TYPE_STRING); g_value_take_string (ws_expr->value, g_strdup_printf ("%s.%s = %s.%s", left_table, MGD_WORKSPACE_OID_FIELD, right_table, MGD_WORKSPACE_OID_FIELD)); operation->operands = g_slist_append (operation->operands, ws_expr); }