Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No explain call #30

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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