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;
}
Ejemplo n.º 2
0
/**
 * gda_sql_select_join_copy
 * @join: a #GdaSqlSelectJoin structure to be copied
 *
 * Creates a new #GdaSqlSelectJoin structure initiated with the values stored in @join.
 *
 * Returns: a new #GdaSqlSelectJoin structure.
 */
GdaSqlSelectJoin *
gda_sql_select_join_copy (GdaSqlSelectJoin *join)
{
	GdaSqlSelectJoin *copy;
	GSList *list;

	if (!join) return NULL;

	copy = gda_sql_select_join_new (NULL);
	copy->type = join->type;
	copy->position = join->position;

	copy->expr = gda_sql_expr_copy (join->expr);
	gda_sql_any_part_set_parent (copy->expr, copy);

	for (list = join->use; list; list = list->next) {
		copy->use = g_slist_prepend (copy->use,
					       gda_sql_field_copy ((GdaSqlField*) list->data));
		gda_sql_any_part_set_parent (copy->use->data, copy);
	}
	copy->use = g_slist_reverse (copy->use);

	return copy;
}
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);

}