void _midgard_query_constraint_add_conditions_to_statement (MidgardQueryExecutor *executor, MidgardQueryConstraintSimple *constraint_simple, GdaSqlStatement *stmt, GdaSqlExpr *where_expr_node) { MidgardQueryConstraint *self = MIDGARD_QUERY_CONSTRAINT (constraint_simple); //GdaConnection *cnc = executor->priv->mgd->priv->connection; MidgardDBObjectClass *dbklass = NULL; if (self->priv->storage && (self->priv->storage != MIDGARD_QUERY_EXECUTOR (executor)->priv->storage)) { dbklass = self->priv->storage->priv->klass; MQE_SET_TABLE_ALIAS (executor, self->priv->storage); } if (!dbklass) dbklass = executor->priv->storage->priv->klass; g_return_if_fail (dbklass != NULL); /* Get table */ //const gchar *table = midgard_core_class_get_table (dbklass); /* Get field name */ GValue field_value = {0, }; midgard_query_holder_get_value (MIDGARD_QUERY_HOLDER (MIDGARD_QUERY_CONSTRAINT (constraint_simple)->priv->property_value), &field_value); GdaSqlStatementSelect *select = stmt->contents; GdaSqlExpr *top_where, *where, *expr; GdaSqlOperation *top_operation, *cond; GValue *value; if (where_expr_node) { top_where = where_expr_node; top_operation = top_where->cond; } else { top_where = select->where_cond; top_operation = top_where->cond; } where = gda_sql_expr_new (GDA_SQL_ANY_PART (top_operation)); top_operation->operands = g_slist_append (top_operation->operands, where); cond = gda_sql_operation_new (GDA_SQL_ANY_PART (where)); where->cond = cond; cond->operator_type = self->priv->op_type; /* Create table_alias.field name */ gchar *table_alias_field; expr = gda_sql_expr_new (GDA_SQL_ANY_PART (cond)); table_alias_field = midgard_core_query_compute_constraint_property (executor, MIDGARD_QUERY_CONSTRAINT (constraint_simple)->priv->storage, g_value_get_string (&field_value)); if (!table_alias_field) g_warning ("Null table.field alias for given '%s'", g_value_get_string (&field_value)); /* TODO, handle error case when table_alias_field is NULL */ g_value_take_string ((value = gda_value_new (G_TYPE_STRING)), table_alias_field); expr->value = value; cond->operands = g_slist_append (cond->operands, expr); expr = gda_sql_expr_new (GDA_SQL_ANY_PART (cond)); /* Create value */ GValue val = {0, }; midgard_query_holder_get_value (MIDGARD_QUERY_CONSTRAINT (constraint_simple)->priv->holder, &val); /*GType v_type = G_VALUE_TYPE (&val); //FIXME, create parameter name::type */ //GValue *dval = gda_value_new (G_TYPE_STRING); //g_value_transform (&val, dval); //expr->param_spec = gda_sql_param_spec_new (dval); //expr->param_spec->g_type = v_type; expr->value = gda_value_new (G_TYPE_STRING); __set_expression_value (expr->value, &val); g_value_unset (&val); cond->operands = g_slist_append (cond->operands, expr); /* increase executor's constraints number */ executor->priv->n_constraints++; }
gchar * midgard_cr_core_query_compute_constraint_property (MidgardCRCoreQueryExecutor *executor, MidgardCRCoreQueryStorage *storage, const gchar *name) { g_return_val_if_fail (executor != NULL, FALSE); g_return_val_if_fail (name != NULL, FALSE); /* Set table alias if it's not set */ if (storage) MQE_SET_TABLE_ALIAS (executor, storage); MidgardCRSQLStorageManager *manager = (MidgardCRSQLStorageManager*) executor->priv->storage_manager; GObjectClass *klass = g_type_class_peek (g_type_from_name (executor->priv->storage->priv->classname)); MidgardCRSQLTableModel *table_model = midgard_cr_core_query_find_table_model_by_name (manager, executor->priv->storage->priv->classname); gchar *table_field = NULL; gchar *table_alias = executor->priv->table_alias; const gchar *table = midgard_cr_storage_model_get_location (MIDGARD_CR_STORAGE_MODEL (table_model)); if (storage) { //table = executor->priv->storage->priv->table; table_alias = storage->priv->table_alias; klass = g_type_class_peek (g_type_from_name (storage->priv->classname)); } gchar **spltd = g_strsplit(name, ".", 0); guint i = 0; guint j = 0; /* We can support max 3 tokens */ while(spltd[i] != NULL) i++; gchar *q_table = NULL; gchar *q_field = NULL; /* case: property */ if (i == 1) { const gchar *property_field = __get_property_colname (MIDGARD_CR_SQL_STORAGE_MANAGER (executor->priv->storage_manager), G_OBJECT_CLASS_NAME (klass), name); if (!property_field) { g_warning ("%s doesn't seem to be registered for %s", name, G_OBJECT_CLASS_NAME (klass)); g_strfreev (spltd); return NULL; } q_table = gda_connection_quote_sql_identifier (MCQE_CNC (executor), table_alias); q_field = gda_connection_quote_sql_identifier (MCQE_CNC (executor), property_field); table_field = g_strdup_printf ("%s.%s", q_table, q_field); } else if (i < 4) { /* Set all pointers we need to generate valid tables' names, aliases or joins */ Psh holder = {NULL, }; holder.table = table; holder.table_alias = table_alias; holder.klass = klass; holder.executor = MIDGARD_CR_CORE_QUERY_EXECUTOR (executor); holder.colname = NULL; while (spltd[j] != NULL) { if (spltd[j+1] == NULL) break; /* Set all pointers we need to generate valid tables' names, aliases or joins */ /* case: metadata.property, attachment.property, property.link, etc */ if (!__compute_reserved_property_constraint (&holder, spltd[j], spltd[j+1])) break; j++; } if (holder.table_alias && holder.colname) { q_table = gda_connection_quote_sql_identifier (MCQE_CNC (executor), holder.table_alias); q_field = gda_connection_quote_sql_identifier (MCQE_CNC (executor), holder.colname); table_field = g_strdup_printf ("%s.%s", q_table, q_field); } } else { g_warning("Failed to parse '%s'. At most 3 tokens allowed", name); } g_strfreev (spltd); g_free (q_table); g_free (q_field); return table_field; }
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; }