From 04f3b80edd899d7e0d538f010bb9af260287754f Mon Sep 17 00:00:00 2001 From: SE park Date: Tue, 28 Jun 2022 13:51:43 +0900 Subject: [PATCH] [CBRD-24285] Problem of sort limit optimization without checking not null of foreign key (#3509) http://jira.cubrid.org/browse/CBRD-24285 check not null of fk when sort limit optimization --- src/object/class_object.h | 5 ++++ src/optimizer/query_graph.c | 47 +++++++++++++++++++++++++++++++++++++ src/optimizer/query_graph.h | 2 ++ 3 files changed, 54 insertions(+) diff --git a/src/object/class_object.h b/src/object/class_object.h index 337a98a1166..0add54d8511 100644 --- a/src/object/class_object.h +++ b/src/object/class_object.h @@ -114,6 +114,11 @@ struct pr_type; (c) == SM_CONSTRAINT_REVERSE_UNIQUE) \ ? true : false ) +#define SM_IS_CONSTRAINT_NOT_NULL_FAMILY(c) \ + (((c) == SM_CONSTRAINT_NOT_NULL || \ + (c) == SM_CONSTRAINT_PRIMARY_KEY) \ + ? true : false ) + #define SM_IS_CONSTRAINT_INDEX_FAMILY(c) \ ((SM_IS_CONSTRAINT_UNIQUE_FAMILY(c) || \ (c) == SM_CONSTRAINT_FOREIGN_KEY || \ diff --git a/src/optimizer/query_graph.c b/src/optimizer/query_graph.c index 631f805e5e1..28c78f15254 100644 --- a/src/optimizer/query_graph.c +++ b/src/optimizer/query_graph.c @@ -1480,6 +1480,10 @@ static QO_SEGMENT * qo_insert_segment (QO_NODE * head, QO_NODE * tail, PT_NODE * node, QO_ENV * env, const char *expr_str) { QO_SEGMENT *seg = NULL; + PT_NODE *entity; + MOP cls; + SM_CLASS_CONSTRAINT *constraints; + SM_ATTRIBUTE *attrp; QO_ASSERT (env, head != NULL); QO_ASSERT (env, env->nsegs < env->Nsegs); @@ -1522,6 +1526,42 @@ qo_insert_segment (QO_NODE * head, QO_NODE * tail, PT_NODE * node, QO_ENV * env, bitset_add (&(QO_NODE_SEGS (head)), QO_SEG_IDX (seg)); + /* check is_not_null */ + entity = QO_NODE_ENTITY_SPEC (head); + if (pt_is_name_node (node) && PT_SPEC_IS_ENTITY (entity)) + { + int i; + bool found = false; + cls = sm_find_class (entity->info.spec.entity_name->info.name.original); + constraints = sm_class_constraints (cls); + + while (constraints != NULL) + { + if (!SM_IS_CONSTRAINT_NOT_NULL_FAMILY (constraints->type)) + { + constraints = constraints->next; + continue; + } + + /* check columns on this constraint */ + for (i = 0; constraints->attributes[i]; i++) + { + attrp = constraints->attributes[i]; + if (intl_identifier_casecmp (node->info.name.original, attrp->header.name) == 0) + { + QO_SEG_IS_NOT_NULL (seg) = true; + found = true; + break; + } + } + if (found) + { + break; + } + constraints = constraints->next; + } + } + env->nsegs++; return seg; @@ -8305,6 +8345,7 @@ qo_seg_clear (QO_ENV * env, int idx) QO_SEG_SHARED_ATTR (seg) = false; QO_SEG_IDX (seg) = idx; QO_SEG_FUNC_INDEX (seg) = false; + QO_SEG_IS_NOT_NULL (seg) = false; bitset_init (&(QO_SEG_INDEX_TERMS (seg)), env); } @@ -9600,6 +9641,12 @@ qo_is_pk_fk_full_join (QO_ENV * env, QO_NODE * fk_node, QO_NODE * pk_node) fk_seg = QO_TERM_INDEX_SEG (term, 1); } + /* fk must have the NOT_NULL constraint */ + if (!QO_SEG_IS_NOT_NULL (fk_seg)) + { + return false; + } + /* make sure pk_seg and fk_seg reference the same position in the two indexes */ for (j = 0; j < pk_idx->nsegs; j++) { diff --git a/src/optimizer/query_graph.h b/src/optimizer/query_graph.h index dc95dfe5ae5..60017a03005 100644 --- a/src/optimizer/query_graph.h +++ b/src/optimizer/query_graph.h @@ -503,6 +503,7 @@ struct qo_segment /* The index of this segment in the corresponding Env's seg array. */ int idx; bool is_function_index; + bool is_not_null; }; #define QO_SEG_ENV(seg) (seg)->env @@ -522,6 +523,7 @@ struct qo_segment #define QO_SEG_IS_OID_SEG(seg) (QO_NODE_OID_SEG(QO_SEG_HEAD(seg)) == seg) #define QO_SEG_INDEX_TERMS(seg) (seg)->index_terms #define QO_SEG_FUNC_INDEX(seg) (seg)->is_function_index +#define QO_SEG_IS_NOT_NULL(seg) (seg)->is_not_null #define OID_SEG_NAME "OID$" struct qo_eqclass