Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 63 additions & 60 deletions mysql_fdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,69 +623,72 @@ mysqlGetForeignRelSize(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntablei
server = GetForeignServer(table->serverid);
user = GetUserMapping(userid, server->serverid);

/* Fetch the options */
options = mysql_get_options(foreigntableid);


/* Fetch options */
options = mysql_get_options(foreigntableid);

/* Connect to the server */
conn = mysql_get_connection(server, user, options);

_mysql_query(conn, "SET sql_mode='ANSI_QUOTES'");

/* Build the query */
initStringInfo(&sql);

pull_varattnos((Node *) baserel->reltargetlist, baserel->relid, &attrs_used);

appendStringInfo(&sql, "EXPLAIN ");
mysql_deparse_select(&sql, root, baserel, attrs_used, options->svr_table, &retrieved_attrs);

/*
* TODO: MySQL seems to have some pretty unhelpful EXPLAIN output, which only
* gives a row estimate for each relation in the statement. We'll use the
* sum of the rows as our cost estimate - it's not great (in fact, in some
* cases it sucks), but it's all we've got for now.
*/
if (_mysql_query(conn, sql.data) != 0)
{
switch(_mysql_errno(conn))
{
case CR_NO_ERROR:
break;

case CR_OUT_OF_MEMORY:
case CR_SERVER_GONE_ERROR:
case CR_SERVER_LOST:
case CR_UNKNOWN_ERROR:
{
char *err = pstrdup(_mysql_error(conn));
mysql_rel_connection(conn);
ereport(ERROR,
(errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION),
errmsg("failed to execute the MySQL query: \n%s", err)));
}
break;
case CR_COMMANDS_OUT_OF_SYNC:
default:
{
char *err = pstrdup(_mysql_error(conn));
ereport(ERROR,
(errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION),
errmsg("failed to execute the MySQL query: \n%s", err)));
}
}
}
result = _mysql_store_result(conn);
if (result)
{
while ((row = _mysql_fetch_row(result)))
rows += row[8] ? atof(row[8]) : 2;

_mysql_free_result(result);
}
if (options->svr_cost == 0)
{
/* Connect to the server */
conn = mysql_get_connection(server, user, options);

_mysql_query(conn, "SET sql_mode='ANSI_QUOTES'");

/* Build the query */
initStringInfo(&sql);

pull_varattnos((Node *) baserel->reltargetlist, baserel->relid, &attrs_used);

appendStringInfo(&sql, "EXPLAIN ");
mysql_deparse_select(&sql, root, baserel, attrs_used, options->svr_table, &retrieved_attrs);

/*
* TODO: MySQL seems to have some pretty unhelpful EXPLAIN output, which only
* gives a row estimate for each relation in the statement. We'll use the
* sum of the rows as our cost estimate - it's not great (in fact, in some
* cases it sucks), but it's all we've got for now.
*/
if (_mysql_query(conn, sql.data) != 0)
{
switch(_mysql_errno(conn))
{
case CR_NO_ERROR:
break;

case CR_OUT_OF_MEMORY:
case CR_SERVER_GONE_ERROR:
case CR_SERVER_LOST:
case CR_UNKNOWN_ERROR:
{
char *err = pstrdup(_mysql_error(conn));
mysql_rel_connection(conn);
ereport(ERROR,
(errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION),
errmsg("failed to execute the MySQL query: \n%s", err)));
}
break;
case CR_COMMANDS_OUT_OF_SYNC:
default:
{
char *err = pstrdup(_mysql_error(conn));
ereport(ERROR,
(errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION),
errmsg("failed to execute the MySQL query: \n%s", err)));
}
}
}
result = _mysql_store_result(conn);
if (result)
{
while ((row = _mysql_fetch_row(result)))
rows += row[8] ? atof(row[8]) : 2;

_mysql_free_result(result);
}
}
else
{
rows = options->svr_cost;
}
baserel->rows = rows;
baserel->tuples = rows;
}
Expand Down
1 change: 1 addition & 0 deletions mysql_fdw.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ typedef struct mysql_opt
char *svr_password; /* MySQL password */
char *svr_database; /* MySQL database name */
char *svr_table; /* MySQL table name */
int svr_cost; /* MySQL table cost */
} mysql_opt;

/*
Expand Down
4 changes: 4 additions & 0 deletions option.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ static struct MySQLFdwOption valid_options[] =
{ "password", UserMappingRelationId },
{ "dbname", ForeignTableRelationId },
{ "table_name", ForeignTableRelationId },
{ "cost", ForeignTableRelationId },

/* Sentinel */
{ NULL, InvalidOid }
Expand Down Expand Up @@ -192,6 +193,9 @@ mysql_get_options(Oid foreigntableid)

if (strcmp(def->defname, "table_name") == 0)
opt->svr_table = defGetString(def);

if (strcmp(def->defname, "cost") == 0)
opt->svr_cost = atoi(defGetString(def));
}
/* Default values, if required */
if (!opt->svr_address)
Expand Down