From b861d104989deb9d404239cf7602a5563ff4807e Mon Sep 17 00:00:00 2001 From: Morgan Douglas Date: Mon, 10 Feb 2025 14:31:01 -0500 Subject: [PATCH] Limit len of sp name for triggers/consumers to 28 Signed-off-by: Morgan Douglas Tweak Signed-off-by: Morgan Douglas Address review Signed-off-by: Morgan Douglas Tweak Signed-off-by: Morgan Douglas Change error message Signed-off-by: Morgan Douglas Remove LUA_TAG_LEN Signed-off-by: Morgan Douglas Misc Signed-off-by: Morgan Douglas Tweak Signed-off-by: Morgan Douglas Less hardcode Signed-off-by: Morgan Douglas Capitalization tweak Signed-off-by: Morgan Douglas Tweak test Signed-off-by: Morgan Douglas --- db/config.c | 4 ++-- db/osqlcomm.c | 2 +- db/translistener.c | 4 ++-- db/trigger.h | 7 ++++--- docs/pages/programming/sql.md | 3 +++ sqlite/src/comdb2build.c | 24 ++++++++++++++++++------ sqlite/src/comdb2lua.c | 23 +++++++++++++---------- tests/consumer.test/t05.expected | 9 +++++++++ tests/consumer.test/t05.sql | 20 ++++++++++++++++++++ 9 files changed, 72 insertions(+), 24 deletions(-) create mode 100644 tests/consumer.test/t05.expected create mode 100644 tests/consumer.test/t05.sql diff --git a/db/config.c b/db/config.c index 0d00dfdc52..40e93af2ff 100644 --- a/db/config.c +++ b/db/config.c @@ -1505,7 +1505,7 @@ static int read_lrl_option(struct dbenv *dbenv, char *line, char *queue = alloca(ltok + 1); tokcpy(tok, ltok, queue); char *bdbq = alloca(ltok + 4); - sprintf(bdbq, "__q%s", queue); + sprintf(bdbq, "%s%s", Q_TAG, queue); if ((tok = segtok(line, len, &st, <ok)) == NULL || ltok == 0) { logmsg(LOGMSG_ERROR, "Expected dump-queue filename\n"); @@ -1531,7 +1531,7 @@ static int read_lrl_option(struct dbenv *dbenv, char *line, char *queue = alloca(ltok + 1); tokcpy(tok, ltok, queue); char *bdbq = alloca(ltok + 4); - sprintf(bdbq, "__q%s", queue); + sprintf(bdbq, "%s%s", Q_TAG, queue); if ((tok = segtok(line, len, &st, <ok)) == NULL || ltok <= 0) { logmsg(LOGMSG_ERROR, "Expected kafka topic\n"); diff --git a/db/osqlcomm.c b/db/osqlcomm.c index b3e9550178..3b3d3b7d2a 100644 --- a/db/osqlcomm.c +++ b/db/osqlcomm.c @@ -3820,7 +3820,7 @@ static int osql_net_type_to_net_uuid_type(int type) int is_tablename_queue(const char *name) { /* See also, __db_open @ /berkdb/db/db_open.c for register_qdb */ - return strncmp(name, "__q", 3) == 0; + return strncmp(name, Q_TAG, 3) == 0; } int osql_send_prepare(osql_target_t *target, unsigned long long rqid, uuid_t uuid, const char *dist_txnid, diff --git a/db/translistener.c b/db/translistener.c index 10c87437b0..93be2d65b3 100644 --- a/db/translistener.c +++ b/db/translistener.c @@ -865,7 +865,7 @@ static int sp_trigger_run(struct javasp_trans_state *javasp_trans_handle, static int sp_trigger_skip(struct stored_proc *sp) { int rc = 0; - const char *prefix = "__q__m"; // identifier for migrated queues + const char *prefix = Q_TAG "__m"; // identifier for migrated queues size_t prefix_len = strlen(prefix); const char *qname = sp->qname; size_t qname_len = strlen(qname); @@ -1461,7 +1461,7 @@ int gather_triggers(struct gather_triggers_arg *arg) struct stored_proc *sp; LISTC_FOR_EACH(&stored_procs, sp, lnk) { e.name = sp->name; - if (strncmp(e.name, "__q", 3) == 0) e.name += 3; + if (strncmp(e.name, Q_TAG, 3) == 0) e.name += 3; struct dbtable *qdb = getqueuebyname(sp->name); if (!qdb) continue; if (qdb->consumers[0] == NULL) continue; diff --git a/db/trigger.h b/db/trigger.h index 5963759170..0096b6bae7 100644 --- a/db/trigger.h +++ b/db/trigger.h @@ -82,11 +82,12 @@ void trigger_reg_to_cpu(trigger_reg_t *); #define trigger_reg_sz(sp_name) \ sizeof(trigger_reg_t) + strlen(sp_name) + 1 + strlen(gbl_myhostname) + 1 +#define Q_TAG "__q" #define Q4SP(var, spname) \ - char var[sizeof("__q") + strlen(spname)]; \ - sprintf(var, "__q%s", spname); + char var[sizeof(Q_TAG) + strlen(spname)]; \ + sprintf(var, "%s%s", Q_TAG, spname); -#define SP4Q(q) ((q) + (sizeof("__q") - 1)) +#define SP4Q(q) ((q) + (sizeof(Q_TAG) - 1)) struct lua_State; void force_unregister(struct lua_State *, trigger_reg_t *); diff --git a/docs/pages/programming/sql.md b/docs/pages/programming/sql.md index 6af0d5712f..cfb217d74f 100644 --- a/docs/pages/programming/sql.md +++ b/docs/pages/programming/sql.md @@ -283,6 +283,9 @@ as new SQL functions with the [CREATE LUA FUNCTION](#create-lua-function) statement, or as triggers with ```CREATE LUA TRIGGER```/ ```CREATE LUA CONSUMER``` statements. +The maximum procedure name length is 31 chars +**unless the procedure will be used by a trigger or a consumer, in which case the limit is 28 chars**. + All procedures have versions. If a version is not provided by the user then the database will give the procedure a numeric version. Versioning allows a more compartmentalized development model. For instance, users may have "beta" and "prod" versions of a procedure diff --git a/sqlite/src/comdb2build.c b/sqlite/src/comdb2build.c index 93498012a4..7f8240d85b 100644 --- a/sqlite/src/comdb2build.c +++ b/sqlite/src/comdb2build.c @@ -1231,7 +1231,9 @@ void comdb2CreateProcedure(Parse* pParse, Token* nm, Token* ver, Token* proc) Vdbe *v = sqlite3GetVdbe(pParse); if (comdb2TokenToStr(nm, spname, sizeof(spname))) { - setError(pParse, SQLITE_MISUSE, "Procedure name is too long"); + char *errMsg = comdb2_asprintf("procedure name must not exceed %d characters", sizeof(spname)-1); + setError(pParse, SQLITE_MISUSE, errMsg); + free(errMsg); return; } @@ -1249,7 +1251,9 @@ void comdb2CreateProcedure(Parse* pParse, Token* nm, Token* ver, Token* proc) } if (ver) { if (comdb2TokenToStr(ver, sp_version, sizeof(sp_version))) { - setError(pParse, SQLITE_MISUSE, "Procedure version is too long"); + char *errMsg = comdb2_asprintf("procedure version must not exceed %d characters", sizeof(sp_version)-1); + setError(pParse, SQLITE_MISUSE, errMsg); + free(errMsg); goto cleanup; } strcpy(sc->fname, sp_version); @@ -1290,7 +1294,9 @@ void comdb2DefaultProcedure(Parse *pParse, Token *nm, Token *ver, int str) Vdbe *v = sqlite3GetVdbe(pParse); if (comdb2TokenToStr(nm, spname, sizeof(spname))) { - setError(pParse, SQLITE_MISUSE, "Procedure name is too long"); + char *errMsg = comdb2_asprintf("procedure name must not exceed %d characters", sizeof(spname)-1); + setError(pParse, SQLITE_MISUSE, errMsg); + free(errMsg); return; } @@ -1299,7 +1305,9 @@ void comdb2DefaultProcedure(Parse *pParse, Token *nm, Token *ver, int str) if (str) { if (comdb2TokenToStr(ver, sp_version, sizeof(sp_version))) { - setError(pParse, SQLITE_MISUSE, "Procedure version is too long"); + char *errMsg = comdb2_asprintf("procedure version must not exceed %d characters", sizeof(sp_version)-1); + setError(pParse, SQLITE_MISUSE, errMsg); + free(errMsg); goto cleanup; } strcpy(sc->fname, sp_version); @@ -1342,7 +1350,9 @@ void comdb2DropProcedure(Parse *pParse, Token *nm, Token *ver, int str) Vdbe *v = sqlite3GetVdbe(pParse); if (comdb2TokenToStr(nm, spname, sizeof(spname))) { - setError(pParse, SQLITE_MISUSE, "Procedure name is too long"); + char *errMsg = comdb2_asprintf("procedure name must not exceed %d characters", sizeof(spname)-1); + setError(pParse, SQLITE_MISUSE, errMsg); + free(errMsg); return; } @@ -1368,7 +1378,9 @@ void comdb2DropProcedure(Parse *pParse, Token *nm, Token *ver, int str) if (str) { if (comdb2TokenToStr(ver, sp_version, sizeof(sp_version))) { - setError(pParse, SQLITE_MISUSE, "Procedure version is too long"); + char *errMsg = comdb2_asprintf("procedure version must not exceed %d characters", sizeof(sp_version)-1); + setError(pParse, SQLITE_MISUSE, errMsg); + free(errMsg); goto cleanup; } strcpy(sc->fname, sp_version); diff --git a/sqlite/src/comdb2lua.c b/sqlite/src/comdb2lua.c index 3f546b823f..360cdfc81e 100644 --- a/sqlite/src/comdb2lua.c +++ b/sqlite/src/comdb2lua.c @@ -21,6 +21,7 @@ struct dbtable; struct dbtable *getqueuebyname(const char *); int bdb_get_sp_get_default_version(const char *, int *); +#define MAX_SPNAME_FOR_TRIGGER MAX_SPNAME-strlen(Q_TAG) // includes null terminator #define COMDB2_DEFAULT_CONSUMER 2 static int comdb2LocateSP(Parse *p, char *sp) @@ -160,10 +161,10 @@ void comdb2CreateTrigger(Parse *parse, int consumer, int seq, Token *proc, Cdb2T if (comdb2AuthenticateUserOp(parse)) return; - char spname[MAX_SPNAME]; + char spname[MAX_SPNAME_FOR_TRIGGER]; if (comdb2TokenToStr(proc, spname, sizeof(spname))) { - sqlite3ErrorMsg(parse, "procedure name is too long"); + sqlite3ErrorMsg(parse, "procedure name must not exceed %d characters", sizeof(spname)-1); return; } @@ -262,10 +263,10 @@ void comdb2DropTrigger(Parse *parse, int consumer, Token *proc) if (comdb2AuthenticateUserOp(parse)) return; - char spname[MAX_SPNAME]; + char spname[MAX_SPNAME_FOR_TRIGGER]; if (comdb2TokenToStr(proc, spname, sizeof(spname))) { - sqlite3ErrorMsg(parse, "Procedure name is too long"); + sqlite3ErrorMsg(parse, "procedure name must not exceed %d characters", sizeof(spname)-1); return; } @@ -285,7 +286,7 @@ void comdb2DropTrigger(Parse *parse, int consumer, Token *proc) #define comdb2CreateFunc(p, proc, pfx, PFX, type, flags) \ do { \ - char spname[MAX_SPNAME]; \ + char spname[MAX_SPNAME_FOR_TRIGGER]; \ struct schema_change_type *sc = new_schemachange_type(); \ sc->kind = SC_ADD_##PFX##FUNC; \ if (comdb2IsDryrun(p)) { \ @@ -299,7 +300,8 @@ void comdb2DropTrigger(Parse *parse, int consumer, Token *proc) } \ } \ if (comdb2TokenToStr(proc, spname, sizeof(spname))) { \ - sqlite3ErrorMsg(p, "procedure name is too long"); \ + sqlite3ErrorMsg(parse, \ + "procedure name must not exceed %d characters", sizeof(spname)-1); \ return; \ } \ if (!comdb2LocateSP(p, spname)) { \ @@ -360,9 +362,10 @@ void comdb2CreateAggFunc(Parse *parse, Token *proc) #define comdb2DropFunc(p, proc, pfx, PFX, type) \ do { \ - char spname[MAX_SPNAME]; \ + char spname[MAX_SPNAME_FOR_TRIGGER]; \ if (comdb2TokenToStr(proc, spname, sizeof(spname))) { \ - sqlite3ErrorMsg(p, "procedure name is too long"); \ + sqlite3ErrorMsg(parse, \ + "procedure name must not exceed %d characters", sizeof(spname)-1); \ return; \ } \ if (find_lua_##pfx##func(spname) == 0) { \ @@ -404,9 +407,9 @@ void comdb2DropScalarFunc(Parse *parse, Token *proc) if (comdb2AuthenticateUserOp(parse)) return; - char spname[MAX_SPNAME]; + char spname[MAX_SPNAME_FOR_TRIGGER]; if (comdb2TokenToStr(proc, spname, sizeof(spname))) { - sqlite3ErrorMsg(parse, "Procedure name is too long"); + sqlite3ErrorMsg(parse, "procedure name must not exceed %d characters", sizeof(spname)-1); return; } diff --git a/tests/consumer.test/t05.expected b/tests/consumer.test/t05.expected new file mode 100644 index 0000000000..994498beb6 --- /dev/null +++ b/tests/consumer.test/t05.expected @@ -0,0 +1,9 @@ +(version='sample') +(version='sample') +(version='sample') +[create procedure len_is_32_______________________ version 'sample' { + local function main() + end +}] failed with rc -3 procedure name must not exceed 31 characters +[create lua consumer len_is_29____________________ on (table t for update of i)] failed with rc -3 procedure name must not exceed 28 characters +(name='len_is_28___________________', type='consumer', tbl_name='t', event='upd', col='i', seq='N') diff --git a/tests/consumer.test/t05.sql b/tests/consumer.test/t05.sql new file mode 100644 index 0000000000..1b5a415895 --- /dev/null +++ b/tests/consumer.test/t05.sql @@ -0,0 +1,20 @@ +create table t(i int)$$ +create procedure len_is_28___________________ version 'sample' { + local function main() + end +}$$ +create procedure len_is_29____________________ version 'sample' { + local function main() + end +}$$ +create procedure len_is_31______________________ version 'sample' { + local function main() + end +}$$ +create procedure len_is_32_______________________ version 'sample' { + local function main() + end +}$$ +create lua consumer len_is_28___________________ on (table t for update of i) +create lua consumer len_is_29____________________ on (table t for update of i) +select * from comdb2_triggers where name like 'len_is_%'