Index: trunk/ippTools/src/disttool.c
===================================================================
--- trunk/ippTools/src/disttool.c	(revision 23742)
+++ trunk/ippTools/src/disttool.c	(revision 23765)
@@ -132,6 +132,232 @@
 static bool definebyqueryMode(pxConfig *config)
 {
-    psError(PS_ERR_PROGRAMMING, true, "-definebyquery is not implemented yet");
-    return false;
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // required
+    PXOPT_LOOKUP_STR(stage, config->args,     "-stage", true, false);
+    PXOPT_LOOKUP_STR(workdir, config->args,   "-workdir", true, false);
+    PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id",  false, false);
+
+    // optional
+    PXOPT_LOOKUP_BOOL(no_magic, config->args, "-no_magic", false);
+    PXOPT_LOOKUP_STR(set_label, config->args, "-set_label", false, false);
+    PXOPT_LOOKUP_S64(limit, config->args, "-limit", false, false);
+    
+    PXOPT_LOOKUP_BOOL(dry_run, config->args, "-dry_run", false);
+
+    // select arguments
+    psMetadata *where = psMetadataAlloc();
+
+    PXOPT_COPY_S64(config->args, where, "-target_id", "distTarget.target_id",    "==");
+    PXOPT_COPY_S64(config->args, where, "-exp_id",    "rawExp.exp_id",           "==");
+    PXOPT_COPY_S64(config->args, where, "-chip_id",   "chipRun.chip_id",         "==");
+    PXOPT_COPY_STR(config->args, where, "-obs_mode",  "rawExp.obs_mode",         "==");
+
+    PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
+
+    psString query = NULL;
+    psString runType = NULL;
+    psString runJoinStr = NULL;
+    if (!strcmp(stage, "raw")) {
+        runType = "rawExp";
+        runJoinStr = "rawExp.exp_id";
+        query = pxDataGet("disttool_definebyquery_raw.sql");
+        if (!query) {
+            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psFree(where);
+            return false;
+        }
+    } else if (!strcmp(stage, "chip")) {
+        runType = "chipRun";
+        runJoinStr = "chipRun.chip_id";
+        query = pxDataGet("disttool_definebyquery_chip.sql");
+        if (!query) {
+            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psFree(where);
+            return false;
+        }
+
+        if (label) {
+            psStringAppend(&query, " AND (chipRun.label = '%s')", label);
+        }
+    } else if (!strcmp(stage, "camera")) {
+        runType = "camRun";
+        query = pxDataGet("disttool_definebyquery_camera.sql");
+        if (!query) {
+            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psFree(where);
+            return false;
+        }
+
+        if (label) {
+            psStringAppend(&query, " AND (camRun.label = '%s')", label);
+        }
+    } else if (!strcmp(stage, "fake")) {
+        runType = "fakeRun";
+        query = pxDataGet("disttool_definebyquery_fake.sql");
+        if (!query) {
+            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psFree(where);
+            return false;
+        }
+
+        if (label) {
+            psStringAppend(&query, " AND (fakeRun.label = '%s')", label);
+        }
+        // fake stage doesn't require magic
+        no_magic = true;
+    } else if (!strcmp(stage, "warp")) {
+        runType = "warpRun";
+        runJoinStr = "warpRun.warp_id";
+        query = pxDataGet("disttool_definebyquery_warp.sql");
+        if (!query) {
+            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psFree(where);
+            return false;
+        }
+
+        if (label) {
+            psStringAppend(&query, " AND (warpRun.label = '%s')", label);
+        }
+
+    } else if (!strcmp(stage, "diff")) {
+        runType = "diffRun";
+        runJoinStr = "diffRun.diff_id";
+        query = pxDataGet("disttool_definebyquery_diff.sql");
+        if (!query) {
+            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psFree(where);
+            return false;
+        }
+
+        if (label) {
+            psStringAppend(&query, " AND (diffRun.label = '%s')", label);
+        }
+
+    } else if (!strcmp(stage, "stack")) {
+        runType = "stackRun";
+        query = pxDataGet("disttool_definebyquery_stack.sql");
+        if (!query) {
+            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psFree(where);
+            return false;
+        }
+
+        if (label) {
+            psStringAppend(&query, " AND (stackRun.label = '%s')", label);
+        }
+        // stack stage doesn't require magic (perhaps let the script do this?
+        no_magic = true;
+    } else {
+        psError(PS_ERR_UNKNOWN, true, "unknown value for stage: %s", stage);
+        psFree(where);
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    psString joinHook = NULL;
+
+    if (!no_magic) {
+        psStringAppend(&query, " AND (distTarget.clean OR %s.magicked)", runType);
+
+        // is selecting by magic_ds_id really interesting?
+        if (magic_ds_id) {
+            if (strcmp(stage, "camera")) {
+                // stage other than camera
+                if (!runJoinStr) {
+                    psError(PS_ERR_PROGRAMMING, true, "cannot select by magic_ds_id for stage: %s", stage);
+                    psFree(query);
+                    return false;
+                }
+                psStringAppend(&joinHook, "\nJOIN magicDSRun ON magicDSRun.stage = distTarget.stage"
+                                              " AND magicDSRun.stage_id = %s", runJoinStr);
+            } else {
+                // camera masks are magicked when the chipRun is magicked
+                // XXX: This is confusing. Is it dangerous?
+                // Maybe I should add a magicked bit to camRun. Note this isn't
+                psStringAppend(&joinHook, "\nJOIN magicDSRun ON magicDSRun.stage = 'chip'"
+                                              " AND magicDSRun.stage_id = chipRun.chip_id");
+            }
+            psStringAppend(&query, " AND (magicDSRun.state = 'full' AND magicDSRun.re_place AND (magic_ds_id = %" PRId64 "))", magic_ds_id);
+        }
+    }
+
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, joinHook ? joinHook : "")) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+    psFree(joinHook);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("warptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    // XXX Remove this debugging output at some point
+    if (!ippdbPrintMetadatas(stdout, output, "newdistRuns", true)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+    if (dry_run) {
+        psFree(output);
+        return true;
+    }
+
+    for (long i=0; i < psArrayLength(output); i++) {
+        psMetadata *md = output->data[i];
+        psString stage = psMetadataLookupStr(NULL, md, "stage");
+        psString run_tag = psMetadataLookupStr(NULL, md, "run_tag");
+        psS64 stage_id = psMetadataLookupS64(NULL, md, "stage_id");
+        psS64 target_id = psMetadataLookupS64(NULL, md, "target_id");
+        bool clean = psMetadataLookupBool(NULL, md, "clean");
+
+        psString outroot = NULL;
+        psStringAppend(&outroot, "%s/%s/%s", workdir, run_tag, stage); 
+
+        if (!distRunInsert(config->dbh,
+                0,      // dist_id
+                target_id,
+                stage,
+                stage_id,
+                set_label,
+                outroot,
+                clean,
+                no_magic,
+                "new",
+                NULL,   // time_stamp
+                0       // fault
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            psFree(outroot);
+            psFree(output);
+            return false;
+        }
+        psFree(outroot);
+    }
+
+    psFree(output);
+
+    return true;
 }
 
