!2845 【bugfixed】解决insert语句右值引用不支持jdbc方式;以及列存在not null约束时默认值与MySQL不一致的问题

Merge pull request !2845 from laishenghao/rightref-bugfixed
This commit is contained in:
opengauss-bot 2023-02-07 06:15:53 +00:00 committed by Gitee
commit 39c2d3eeef
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
18 changed files with 1550 additions and 362 deletions

View File

@ -111,6 +111,8 @@ static ReplicaIdentityStmt* _copyReplicaIdentityStmt(const ReplicaIdentityStmt*
static AlterSystemStmt* _copyAlterSystemStmt(const AlterSystemStmt* from);
#endif
static void CopyCursorFields(const Cursor_Data* from, Cursor_Data* newnode);
static RightRefState* CopyRightRefState(const RightRefState* from);
/* ****************************************************************
* plannodes.h copy functions
* ****************************************************************
@ -237,6 +239,8 @@ static void CopyPlanFields(const Plan* from, Plan* newnode)
COPY_SCALAR_FIELD(pred_startup_time);
COPY_SCALAR_FIELD(pred_total_time);
COPY_SCALAR_FIELD(pred_max_memory);
newnode->rightRefState = CopyRightRefState(from->rightRefState);
}
/*
@ -4643,6 +4647,45 @@ static Query* _copyQuery(const Query* from)
COPY_SCALAR_FIELD(isReplace);
}
newnode->rightRefState = CopyRightRefState(from->rightRefState);
return newnode;
}
static RightRefState* CopyRightRefState(const RightRefState* from)
{
if (!from) {
return nullptr;
}
RightRefState* newnode = (RightRefState*)palloc0(sizeof(RightRefState));
COPY_SCALAR_FIELD(isSupported);
COPY_SCALAR_FIELD(isInsertHasRightRef);
COPY_SCALAR_FIELD(explicitAttrLen);
if (from->explicitAttrLen > 0) {
COPY_POINTER_FIELD(explicitAttrNos, from->explicitAttrLen * sizeof(int));
}
if (from->constValues && from->colCnt > 0) {
newnode->constValues = (Const**)palloc0(sizeof(Const*) * from->colCnt);
for (int i = 0; i < from->colCnt; ++i) {
if (from->constValues[i]) {
newnode->constValues[i] = _copyConst(from->constValues[i]);
}
}
}
COPY_SCALAR_FIELD(colCnt);
/* ignore values, hasExecs, isNulls */
COPY_SCALAR_FIELD(isUpsert);
COPY_SCALAR_FIELD(isUpsertHasRightRef);
COPY_SCALAR_FIELD(usExplicitAttrLen);
if (from->usExplicitAttrLen > 0) {
COPY_POINTER_FIELD(usExplicitAttrNos, from->usExplicitAttrLen * sizeof(int));
}
return newnode;
}

View File

@ -86,6 +86,14 @@
return false; \
} while (0)
/* Check whether a field is null */
#define CHECK_ANY_NULL(fildname) \
do { \
if (a->fildname == nullptr || b->fildname == nullptr) { \
return false; \
} \
} while (0)
/* Compare a parse location field (this is a no-op, per note above) */
#define COMPARE_LOCATION_FIELD(fldname) ((void)0)
@ -842,6 +850,54 @@ static bool _equalPlaceHolderInfo(const PlaceHolderInfo* a, const PlaceHolderInf
return true;
}
static bool _equalRightRefState(const RightRefState* a, const RightRefState* b)
{
if (a == b) {
return true;
}
if (a == nullptr || b == nullptr) {
return false;
}
COMPARE_SCALAR_FIELD(isSupported);
COMPARE_SCALAR_FIELD(isInsertHasRightRef);
COMPARE_SCALAR_FIELD(explicitAttrLen);
COMPARE_SCALAR_FIELD(colCnt);
COMPARE_SCALAR_FIELD(isUpsert);
COMPARE_SCALAR_FIELD(isUpsertHasRightRef);
COMPARE_SCALAR_FIELD(usExplicitAttrLen);
/* ignore values, hasExecs, isNulls fields */
if (a->explicitAttrNos != b->explicitAttrNos) {
CHECK_ANY_NULL(explicitAttrNos);
if (a->explicitAttrLen > 0) {
COMPARE_POINTER_FIELD(explicitAttrNos, a->explicitAttrLen);
}
}
if (a->usExplicitAttrNos != b->usExplicitAttrNos) {
CHECK_ANY_NULL(usExplicitAttrNos);
if (a->usExplicitAttrLen > 0) {
COMPARE_POINTER_FIELD(usExplicitAttrNos, a->usExplicitAttrLen);
}
}
if (a->constValues != b->constValues) {
CHECK_ANY_NULL(constValues);
if (a->colCnt > 0) {
for (int i = 0; i < a->colCnt; ++i) {
if (a->constValues[i] != b->constValues[i]) {
CHECK_ANY_NULL(constValues[i]);
COMPARE_NODE_FIELD(constValues[i]);
}
}
}
}
return true;
}
/*
* Stuff from parsenodes.h
*/
@ -904,6 +960,10 @@ static bool _equalQuery(const Query* a, const Query* b)
COMPARE_SCALAR_FIELD(isReplace);
}
if (!_equalRightRefState(a->rightRefState, b->rightRefState)) {
return false;
}
return true;
}

View File

@ -155,6 +155,29 @@
} \
} while (0)
#define WRITE_BASE_TYPE_ARRAY(fldname, size, format) \
do { \
appendStringInfo(str, " :" CppAsString(fldname) " "); \
if (size <= 0) { \
appendStringInfo(str, "<>"); \
} else { \
for (int i = 0; i < size; i++) { \
appendStringInfo(str, format, node->fldname[i]); \
} \
} \
} while(0)
#define WRITE_NODE_ARRAY(fldname, size) \
do { \
if (node->fldname == nullptr || size <= 0) { \
appendStringInfo(str, " :" CppAsString(fldname) " <>"); \
} else { \
for (int i = 0; i < size; i++) { \
WRITE_NODE_FIELD(fldname[i]); \
} \
} \
} while (0)
/*
* Write full-text search configuration's name out of its oid
*
@ -4386,6 +4409,31 @@ static void _outHintState(StringInfo str, HintState* node)
}
}
static void _outRightRefState(StringInfo str, RightRefState* node)
{
if (node == nullptr) {
appendStringInfo(str, "<>");
return;
}
appendStringInfoChar(str, '{');
WRITE_NODE_TYPE("RIGHTREFSTATE");
WRITE_BOOL_FIELD(isSupported);
WRITE_BOOL_FIELD(isInsertHasRightRef);
WRITE_INT_FIELD(explicitAttrLen);
WRITE_BASE_TYPE_ARRAY(explicitAttrNos, node->explicitAttrLen, "%d ");
WRITE_INT_FIELD(colCnt);
WRITE_NODE_ARRAY(constValues, node->colCnt);
/* ignore values, hasExecs, isNulls fields */
WRITE_BOOL_FIELD(isUpsert);
WRITE_BOOL_FIELD(isUpsertHasRightRef);
WRITE_INT_FIELD(usExplicitAttrLen);
WRITE_BASE_TYPE_ARRAY(usExplicitAttrNos, node->usExplicitAttrLen, "%d ");
appendStringInfoChar(str, '}');
}
static void _outQuery(StringInfo str, Query* node)
{
WRITE_NODE_TYPE("QUERY");
@ -4499,6 +4547,10 @@ static void _outQuery(StringInfo str, Query* node)
if (t_thrd.proc->workingVersionNum >= REPLACE_INTO_VERSION_NUM) {
WRITE_BOOL_FIELD(isReplace);
}
if (t_thrd.proc->workingVersionNum >= INSERT_RIGHT_REF_VERSION_NUM) {
appendStringInfo(str, " :" CppAsString(rightRefState) " ");
_outRightRefState(str, node->rightRefState);
}
}
static void _outWithCheckOption(StringInfo str, const WithCheckOption* node)

View File

@ -175,6 +175,19 @@ THR_LOCAL bool skip_read_extern_fields = false;
} \
} while (0)
#define READ_INT_ARRAY_CAN_NULL(fldname, size) \
if (local_node->size > 0) { \
READ_INT_ARRAY(fldname, size); \
} else { \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* read <> */ \
if (token == nullptr || token[0] != '<' || token[1] != '>') { \
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE), \
errmsg("did not find '<>' at end of null array"))); \
} \
local_node->fldname = nullptr; \
}
#define READ_DOUBLE_ARRAY(fldname, size) \
do { \
local_node->fldname = (double*)palloc(local_node->size * sizeof(double)); \
@ -405,6 +418,18 @@ THR_LOCAL bool skip_read_extern_fields = false;
securec_check(reterrno, "\0", "\0"); \
} while (0)
#define READ_NODE_ARRAY(fldname, size, itemtype) \
do { \
if (size <= 0) { \
READ_NODE_FIELD(fldname); /* must be null */ \
} else { \
local_node->fldname = (itemtype*)palloc0(sizeof(itemtype) * (size)); \
for (int i = 0; i < size; i++) { \
READ_NODE_FIELD(fldname[i]); \
} \
} \
} while (0)
/* Read a bitmapset field */
#define READ_BITMAPSET_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
@ -1409,6 +1434,68 @@ static HintState* _readHintState()
READ_DONE();
}
static RightRefState* _readRightRefState(Query* query)
{
check_stack_depth();
RightRefState* local_node = (RightRefState*)palloc0(sizeof(RightRefState));
char* token = nullptr;
int length = 0;
READ_BOOL_FIELD(isSupported);
READ_BOOL_FIELD(isInsertHasRightRef);
READ_INT_FIELD(explicitAttrLen);
READ_INT_ARRAY_CAN_NULL(explicitAttrNos, explicitAttrLen);
READ_INT_FIELD(colCnt);
READ_NODE_ARRAY(constValues, local_node->colCnt, Const*);
/* ignore values, hasExecs, isNulls fields */
READ_BOOL_FIELD(isUpsert);
READ_BOOL_FIELD(isUpsertHasRightRef);
READ_INT_FIELD(usExplicitAttrLen);
READ_INT_ARRAY_CAN_NULL(usExplicitAttrNos, usExplicitAttrLen);
token = pg_strtok(&length);
if (token == nullptr || token[0] != '}') {
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE),
errmsg("did not find '}' at end of RightRefState node")));
}
READ_DONE();
}
static RightRefState* _readRightRefStateWrap(Query* query)
{
char* token = nullptr;
int length = 0;
token = pg_strtok(&length); /* skip :fldname */
token = pg_strtok(&length, false);
if (length == 0) {
if (token && token[0] == '<' && token[1] == '>') {
token = pg_strtok(&length); /* skip <> */
}
return nullptr;
}
token = pg_strtok(&length); /* left brace */
if (token == nullptr || token[0] != '{') {
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE),
errmsg("did not find '{' at end of RightRefState node")));
}
token = pg_strtok(&length); /* read node name */
if (length != 13 && memcmp(token, "RIGHTREFSTATE", 13) != 0) {
ereport(ERROR, (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE),
errmsg("_readRightRefStateWrap(): badly formatted node string \"%s\"...", token)));
}
if (token != nullptr) {
token = nullptr;
}
return _readRightRefState(query);
}
/*
* _readQuery
*/
@ -1544,6 +1631,10 @@ static Query* _readQuery(void)
IF_EXIST(isReplace) {
READ_BOOL_FIELD(isReplace);
}
IF_EXIST(rightRefState) {
local_node->rightRefState = _readRightRefStateWrap(local_node);
}
READ_DONE();
}

View File

@ -17,6 +17,7 @@
#include "postgres.h"
#include "knl/knl_variable.h"
#include "catalog/pg_enum.h"
#include "catalog/pg_type.h"
#include "catalog/pg_proc.h"
#include "catalog/gs_package.h"
@ -105,6 +106,74 @@ static inline bool IsAutoIncrementColumn(TupleDesc rdAtt, int attrNo)
return rdAtt->constr && rdAtt->constr->cons_autoinc && rdAtt->constr->cons_autoinc->attnum == attrNo;
}
static bool IsBaseRightRefSupportType(Oid oid)
{
switch(oid) {
case BOOLOID:
case BYTEAOID:
case CHAROID:
case NAMEOID:
case INT8OID:
case INT2OID:
case INT1OID:
case INT4OID:
case TEXTOID:
case INT16OID:
case RAWOID:
case BLOBOID:
case CLOBOID:
case JSONOID:
case XMLOID:
case POINTOID:
case LSEGOID:
case PATHOID:
case BOXOID:
case POLYGONOID:
case FLOAT4OID:
case FLOAT8OID:
case ABSTIMEOID:
case RELTIMEOID:
case TINTERVALOID:
case CIRCLEOID:
case CASHOID:
case MACADDROID:
case INETOID:
case CIDROID:
case BPCHAROID:
case VARCHAROID:
case NVARCHAR2OID:
case DATEOID:
case TIMEOID:
case TIMESTAMPOID:
case TIMESTAMPTZOID:
case INTERVALOID:
case TIMETZOID:
case BITOID:
case VARBITOID:
case NUMERICOID:
case UUIDOID:
case TSVECTOROID:
case TSQUERYOID:
case JSONBOID:
case INT4RANGEOID:
case NUMRANGEOID:
case TSRANGEOID:
case TSTZRANGEOID:
case DATERANGEOID:
case INT8RANGEOID:
case CSTRINGOID:
case INTERNALOID:
case SMALLDATETIMEOID:
case HLL_OID:
case HASH16OID:
case HASH32OID:
return true;
default: {
return false;
}
}
}
static void AddDefaultExprNode(ParseState* pstate)
{
RightRefState* refState = pstate->rightRefState;
@ -152,6 +221,37 @@ static void AddDefaultExprNode(ParseState* pstate)
refState->constValues[i] = nullptr;
}
}
/* support not null constraint */
if (refState->constValues[i] == nullptr && attTup && attTup->attnotnull) {
Datum datum;
if (IsBaseRightRefSupportType(attTup->atttypid)) {
datum = GetTypeZeroValue(attTup);
refState->constValues[i] = makeConst(attTup->atttypid, attTup->atttypmod, attTup->attcollation,
attTup->attlen, datum, false, attTup->attbyval);
} else if (type_is_enum(attTup->atttypid)) {
Relation enumRel = heap_open(EnumRelationId, AccessShareLock);
CatCList* items = SearchSysCacheList1(ENUMTYPOIDNAME, ObjectIdGetDatum(attTup->atttypid));
int itemCnt = items->n_members;
for (int eindex = 0; eindex < itemCnt; ++eindex) {
HeapTuple enumTup = t_thrd.lsc_cxt.FetchTupleFromCatCList(items, eindex);
Form_pg_enum item = (Form_pg_enum)GETSTRUCT(enumTup);
if (item && item->enumsortorder == 1) {
datum = DirectFunctionCall2(enum_in, CStringGetDatum(pstrdup(NameStr(item->enumlabel))), attTup->atttypid);
refState->constValues[i] = makeConst(attTup->atttypid, attTup->atttypmod, attTup->attcollation,
attTup->attlen, datum, false, attTup->attbyval);
break;
}
}
ReleaseSysCacheList(items);
heap_close(enumRel, AccessShareLock);
} else if (type_is_set(attTup->atttypid)) {
datum = CStringGetTextDatum("");
refState->constValues[i] = makeConst(attTup->atttypid, attTup->atttypmod, attTup->attcollation,
attTup->attlen, datum, false, attTup->attbyval);
}
}
}
}

View File

@ -59,7 +59,7 @@ bool open_join_children = true;
bool will_shutdown = false;
/* hard-wired binary version number */
const uint32 GRAND_VERSION_NUM = 92841;
const uint32 GRAND_VERSION_NUM = 92842;
const uint32 SELECT_INTO_VAR_VERSION_NUM = 92834;
const uint32 DOLPHIN_ENABLE_DROP_NUM = 92830;
@ -117,6 +117,7 @@ const uint32 PLAN_SELECT_VERSION_NUM = 92826;
const uint32 REPLACE_INTO_VERSION_NUM = 92828;
const uint32 PG_AUTHID_PASSWORDEXT_VERSION_NUM = 92830;
const uint32 SUPPORT_VIEW_AUTO_UPDATABLE = 92838;
const uint32 INSERT_RIGHT_REF_VERSION_NUM = 92842;
/* Version number of the guc parameter backend_version added in V500R001C20 */
const uint32 V5R1C20_BACKEND_VERSION_NUM = 92305;

View File

@ -440,9 +440,8 @@ void ExecuteQuery(ExecuteStmt* stmt, IntoClause* intoClause, const char* querySt
eflags = 0;
count = FETCH_ALL;
}
bool checkSQLBypass = IS_PGXC_DATANODE && !psrc->gpc.status.InShareTable() &&
(psrc->cplan == NULL) && (psrc->is_checked_opfusion == false);
if (checkSQLBypass) {
if (OpFusion::IsSqlBypass(psrc, plan_list)) {
psrc->opFusionObj =
OpFusion::FusionFactory(OpFusion::getFusionType(cplan, paramLI, NULL),
u_sess->cache_mem_cxt, psrc, NULL, paramLI);

View File

@ -2236,7 +2236,7 @@ void exec_init_poolhandles(void)
#endif
}
static bool IsRightRefState(List* plantreeList)
bool IsRightRefState(List* plantreeList)
{
if (!plantreeList || !list_length(plantreeList)) {
return false;
@ -4899,8 +4899,7 @@ static void exec_bind_message(StringInfo input_message)
portal->nextval_default_expr_type = psrc->nextval_default_expr_type;
if (IS_PGXC_DATANODE && psrc->cplan == NULL && !psrc->gpc.status.InShareTable() &&
psrc->is_checked_opfusion == false) {
if (OpFusion::IsSqlBypass(psrc, cplan->stmt_list)) {
psrc->opFusionObj = OpFusion::FusionFactory(OpFusion::getFusionType(cplan, params, NULL),
u_sess->cache_mem_cxt, psrc, NULL, params);
psrc->is_checked_opfusion = true;
@ -10712,9 +10711,7 @@ static void exec_one_in_batch(CachedPlanSource* psrc, ParamListInfo params, int
portal->stmts = *gpcCopyStmts;
}
bool checkSQLBypass = IS_PGXC_DATANODE && !psrc->gpc.status.InShareTable() &&
(psrc->cplan == NULL) && (psrc->is_checked_opfusion == false);
if (checkSQLBypass) {
if (OpFusion::IsSqlBypass(psrc, cplan->stmt_list)) {
psrc->opFusionObj = OpFusion::FusionFactory(OpFusion::getFusionType(cplan, params, NULL),
u_sess->cache_mem_cxt, psrc, NULL, params);
psrc->is_checked_opfusion = true;

View File

@ -70,6 +70,7 @@
#include "utils/json.h"
#include "utils/jsonb.h"
#include "utils/xml.h"
#include "utils/rangetypes.h"
#include "commands/sequence.h"
static bool get_last_attnums(Node* node, ProjectionInfo* projInfo);
@ -2664,11 +2665,66 @@ Datum GetTypeZeroValue(Form_pg_attribute att_tup)
result = (Datum)DirectFunctionCall3(bit_in, CStringGetDatum(""), ObjectIdGetDatum(0), Int32GetDatum(-1));
break;
}
case VARBITOID: {
result = (Datum)DirectFunctionCall3(varbit_in, CStringGetDatum(""), ObjectIdGetDatum(0), Int32GetDatum(-1));
break;
}
case NUMERICOID: {
result =
(Datum)DirectFunctionCall3(numeric_in, CStringGetDatum("0"), ObjectIdGetDatum(0), Int32GetDatum(0));
break;
}
case CIDROID: {
result = DirectFunctionCall1(cidr_in, CStringGetDatum("0.0.0.0"));
break;
}
case INETOID: {
result = DirectFunctionCall1(inet_in, CStringGetDatum("0.0.0.0"));
break;
}
case MACADDROID: {
result = (Datum)DirectFunctionCall1(macaddr_in, CStringGetDatum("00:00:00:00:00:00"));
break;
}
case NUMRANGEOID:
case INT8RANGEOID:
case INT4RANGEOID: {
Type targetType = typeidType(att_tup->atttypid);
result = stringTypeDatum(targetType, "(0,0)", att_tup->atttypmod, true);
ReleaseSysCache(targetType);
break;
}
case TSRANGEOID:
case TSTZRANGEOID: {
Type targetType = typeidType(att_tup->atttypid);
result = stringTypeDatum(targetType, "(1970-01-01 00:00:00,1970-01-01 00:00:00)", att_tup->atttypmod, true);
ReleaseSysCache(targetType);
break;
}
case DATERANGEOID: {
Type targetType = typeidType(att_tup->atttypid);
result = stringTypeDatum(targetType, "(1970-01-01,1970-01-01)", att_tup->atttypmod, true);
ReleaseSysCache(targetType);
break;
}
case HASH16OID: {
Type targetType = typeidType(att_tup->atttypid);
result = stringTypeDatum(targetType, "0", att_tup->atttypmod, true);
ReleaseSysCache(targetType);
break;
}
case HASH32OID: {
Type targetType = typeidType(att_tup->atttypid);
result = stringTypeDatum(targetType, "00000000000000000000000000000000", att_tup->atttypmod, true);
ReleaseSysCache(targetType);
break;
}
case TSVECTOROID: {
Type targetType = typeidType(att_tup->atttypid);
result = stringTypeDatum(targetType, "", att_tup->atttypmod, true);
ReleaseSysCache(targetType);
break;
}
default: {
bool typeIsVarlena = (!att_tup->attbyval) && (att_tup->attlen == -1);
if (typeIsVarlena) {

View File

@ -693,18 +693,23 @@ DESCR("range of integers");
DATA(insert OID = 3905 ( _int4range PGNSP PGUID -1 f b A f t \054 0 3904 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 3906 ( numrange PGNSP PGUID -1 f r R f t \054 0 0 3907 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DESCR("range of numerics");
#define NUMRANGEOID 3906
DATA(insert OID = 3907 ( _numrange PGNSP PGUID -1 f b A f t \054 0 3906 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 3908 ( tsrange PGNSP PGUID -1 f r R f t \054 0 0 3909 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DESCR("range of timestamps without time zone");
#define TSRANGEOID 3908
DATA(insert OID = 3909 ( _tsrange PGNSP PGUID -1 f b A f t \054 0 3908 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 3910 ( tstzrange PGNSP PGUID -1 f r R f t \054 0 0 3911 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DESCR("range of timestamps with time zone");
#define TSTZRANGEOID 3910
DATA(insert OID = 3911 ( _tstzrange PGNSP PGUID -1 f b A f t \054 0 3910 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 3912 ( daterange PGNSP PGUID -1 f r R f t \054 0 0 3913 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DESCR("range of dates");
#define DATERANGEOID 3912
DATA(insert OID = 3913 ( _daterange PGNSP PGUID -1 f b A f t \054 0 3912 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 3926 ( int8range PGNSP PGUID -1 f r R f t \054 0 0 3927 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DESCR("range of bigints");
#define INT8RANGEOID 3926
DATA(insert OID = 3927 ( _int8range PGNSP PGUID -1 f b A f t \054 0 3926 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
/*
* pseudo-types

View File

@ -119,6 +119,7 @@ extern const uint32 MAT_VIEW_RECURSIVE_VERSION_NUM;
extern const uint32 SUPPORT_VIEW_AUTO_UPDATABLE;
extern const uint32 FDW_SUPPORT_JOIN_AGG_VERSION_NUM;
extern const uint32 UNION_NULL_VERSION_NUM;
extern const uint32 INSERT_RIGHT_REF_VERSION_NUM;
extern void register_backend_version(uint32 backend_version);
extern bool contain_backend_version(uint32 version_number);

View File

@ -43,6 +43,7 @@ typedef unsigned long (OpFusion::*OpFusionExecfuncType)(Relation rel, ResultRelI
extern void report_qps_type(CmdType commandType);
extern void ExecCheckXactReadOnly(PlannedStmt* plannedstmt);
extern bool IsRightRefState(List* plantreeList);
EState* CreateExecutorStateForOpfusion(MemoryContext saveCxt, MemoryContext tmpCxt);
void FreeExecutorStateForOpfusion(EState* estate);
@ -154,6 +155,13 @@ public:
return (m_global && m_global->m_is_global);
}
inline static bool IsSqlBypass(CachedPlanSource* psrc, List* stmtList)
{
return (IS_PGXC_DATANODE && !psrc->gpc.status.InShareTable() &&
psrc->cplan == NULL && psrc->is_checked_opfusion == false &&
!IsRightRefState(stmtList));
}
public:
struct ConstLoc {
Datum constValue;

View File

@ -34,5 +34,6 @@ extern void AddStartWithTargetRelInfo(ParseState* pstate, Node* relNode,
extern void AdaptSWSelectStmt(ParseState *pstate, SelectStmt *stmt);
extern bool IsQuerySWCBRewrite(Query *query);
extern bool IsSWCBRewriteRTE(RangeTblEntry *rte);
extern Datum GetTypeZeroValue(Form_pg_attribute att_tup);
#endif /* PARSE_EXPR_H */

View File

@ -1,31 +1,21 @@
create database rightref with dbcompatibility 'B';
\c rightref
-- test fields order
create table test_order_t(n1 int default 100, n2 int default 100, s int);
insert into test_order_t values(1000, 1000, n1 + n2);
insert into test_order_t(s, n1, n2) values(n1 + n2, 300, 300);
select * from test_order_t;
n1 | n2 | s
------+------+------
1000 | 1000 | 2000
300 | 300 | 200
(2 rows)
drop table test_order_t;
-- test non-idempotent function
create table non_idempotent_t(c1 float, c2 float, c3 float);
insert into non_idempotent_t values(random(), c1, c1);
select c1 = c2 as f1, c1 = c3 as f2 from non_idempotent_t;
f1 | f2
----+----
t | t
(1 row)
drop table non_idempotent_t;
-- test auto increment
create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);
NOTICE: CREATE TABLE will create implicit sequence "auto_increment_t_c1_seq" for serial column "auto_increment_t.c1"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "auto_increment_t_pkey" for table "auto_increment_t"
insert into auto_increment_t values(1, c1, c1, c1);
insert into auto_increment_t values(2, 0, c1, c1);
insert into auto_increment_t values(3, 0, c1, c1);
@ -33,36 +23,14 @@ insert into auto_increment_t values(4, -1, c1, c1);
insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);
insert into auto_increment_t values(5, c1, c1, c1);
select * from auto_increment_t order by n;
n | c1 | c2 | c3
---+------+----+----
1 | 1 | 0 | 0
2 | 2 | 0 | 0
3 | 3 | 0 | 0
4 | -1 | -1 | -1
5 | 1000 | 0 | 0
5 | 1001 | 0 | 0
(6 rows)
drop table auto_increment_t;
-- test series
create table test_series_t(c1 int, c2 int, c3 int);
insert into test_series_t values(c2 + 10, generate_series(1, 10), c2 * 2);
select * from test_series_t;
c1 | c2 | c3
----+----+----
| 1 | 2
| 2 | 4
| 3 | 6
| 4 | 8
| 5 | 10
| 6 | 12
| 7 | 14
| 8 | 16
| 9 | 18
| 10 | 20
(10 rows)
drop table test_series_t;
-- test upsert
-- 1
create table upser(c1 int, c2 int, c3 int);
@ -73,24 +41,6 @@ insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 1
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
on duplicate key update c2 = 2000, c3 = 2000;
select * from upser order by c1;
c1 | c2 | c3
----+------+------
1 | 10 | 10
2 | 10 | 10
3 | 10 | 10
4 | 10 | 10
5 | 2000 | 2000
6 | 2000 | 2000
7 | 2000 | 2000
8 | 2000 | 2000
9 | 2000 | 2000
10 | 2000 | 2000
11 | 100 | 100
12 | 100 | 100
13 | 100 | 100
14 | 100 | 100
15 | 100 | 100
(15 rows)
-- 2
truncate upser;
@ -100,54 +50,21 @@ insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 1
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
select * from upser order by c1;
c1 | c2 | c3
----+-----+-----
1 | 10 | 10
2 | 10 | 10
3 | 10 | 10
4 | 10 | 10
5 | 15 | 25
6 | 16 | 26
7 | 17 | 27
8 | 18 | 28
9 | 19 | 29
10 | 20 | 30
11 | 100 | 100
12 | 100 | 100
13 | 100 | 100
14 | 100 | 100
15 | 100 | 100
(15 rows)
-- 3
truncate upser;
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10),
(7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100), (8, c1 + 100, 100),
(9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100), (12, c1 + 100, 100),
(13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
select * from upser order by c1;
c1 | c2 | c3
----+-----+-----
1 | 10 | 10
2 | 10 | 10
3 | 10 | 10
4 | 10 | 10
5 | 15 | 25
6 | 16 | 26
7 | 17 | 27
8 | 18 | 28
9 | 19 | 29
10 | 20 | 30
11 | 111 | 100
12 | 112 | 100
13 | 113 | 100
14 | 114 | 100
15 | 115 | 130
(15 rows)
drop table upser;
-- test var
create table with_var(a int default 999);
create function with_var_func() return int as
@ -158,20 +75,13 @@ begin
return a;
end;
/
call with_var_func();
with_var_func
---------------
666
(1 row)
call with_var_func();
select * from with_var;
a
-----
666
(1 row)
drop function with_var_func;
drop table with_var;
-- test num type
create table num_default_t (
n serial,
@ -200,7 +110,7 @@ create table num_default_t (
c23 float default random() * 100,
c24 float
);
NOTICE: CREATE TABLE will create implicit sequence "num_default_t_n_seq" for serial column "num_default_t.n"
insert into num_default_t values(1);
insert into num_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
@ -209,35 +119,15 @@ insert into num_default_t values(3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
c21, c22, c23, c20);
insert into num_default_t(n, c23, c24) values(4, default, c23);
select 3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21
from num_default_t;
?column? | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21
----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+--------+-----+-------+-----+-----+-----+------
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
(4 rows)
select (c23 = c24) as equal from num_default_t where n = 4;
equal
-------
t
(1 row)
select (c22 is null) as c22_is_null, (c23 is null) as c23_is_null from num_default_t where n = 2 or n = 3;
c22_is_null | c23_is_null
-------------+-------------
t | t
t | t
(2 rows)
select (c22 is not null) as c22_is_not_null, (c23 is not null) as c23_is_not_null from num_default_t where n = 1;
c22_is_not_null | c23_is_not_null
-----------------+-----------------
t | t
(1 row)
-- test char type
create table char_default_t(
@ -255,17 +145,12 @@ create table char_default_t(
c11 varchar(20) default concat('hello', ' world'),
c12 varchar(20)
);
NOTICE: CREATE TABLE will create implicit sequence "char_default_t_n_seq" for serial column "char_default_t.n"
insert into char_default_t values(1);
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
select * from char_default_t;
n | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12
---+------------+----+-----+---------+-------+----+-------+----+-----+-----+-------------+-------------
1 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | hello world |
2 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | |
3 | char20 | | vc3 | vc3 vc4 | vc210 | | c31 | | c33 | c34 | hello world | hello world
(3 rows)
-- test time type
create table time_default_t(
@ -284,39 +169,25 @@ create table time_default_t(
c12 time with time zone default current_time,
c13 time
);
NOTICE: CREATE TABLE will create implicit sequence "time_default_t_n_seq" for serial column "time_default_t.n"
insert into time_default_t values(1);
insert into time_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
insert into time_default_t values(3, default, c1, default, c3, default, default, c6,
default, c8, default, c10, default, c12);
select n, c1, c2, c3, c4, c5 from time_default_t;
n | c1 | c2 | c3 | c4 | c5
---+--------------------------+--------------------------+------------+------------+----------
1 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
2 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
3 | Mon Dec 12 22:22:22 2022 | Mon Dec 12 22:22:22 2022 | 12-12-2022 | 12-12-2022 | 22:22:22
(3 rows)
select (c6 is not null) as c6_is_not_null,
(c8 is not null) as c8_is_not_null,
(c10 is not null) as c10_is_not_null,
(c12 is not null) as c12_is_not_null
from time_default_t where n = 1 or n = 3;
c6_is_not_null | c8_is_not_null | c10_is_not_null | c12_is_not_null
----------------+----------------+-----------------+-----------------
t | t | t | t
t | t | t | t
(2 rows)
select (c6 is not null) c6_is_not_null,
(c8 is null) as c8_is_null,
(c10 is null) as c10_is_null,
(c12 is null) as c12_is_null
from time_default_t where n = 2;
c6_is_not_null | c8_is_null | c10_is_null | c12_is_null
----------------+------------+-------------+-------------
t | t | t | t
(1 row)
select (c1=c2) as c1c2,
(c3=c4) as c3c4,
@ -325,10 +196,183 @@ select (c1=c2) as c1c2,
(c10=c11) as c10c11,
(c12=c13) as c12c13
from time_default_t where n = 3;
c1c2 | c3c4 | c6c7 | c8c9 | c10c11 | c12c13
------+------+------+------+--------+--------
t | t | t | t | t | t
(1 row)
-- test num type not null
create table num_notnull_t (
n serial not null,
c1 int not null,
c2 int not null,
c3 tinyint not null,
c4 tinyint not null,
c5 smallint not null,
c6 smallint not null,
c7 integer not null,
c8 integer not null,
c9 binary_integer not null,
c10 bigint not null,
c11 bigint not null,
c12 boolean not null,
c13 boolean not null,
c14 numeric not null,
c15 numeric(10, 3) not null,
c16 decimal not null,
c17 dec(21, 6) not null,
c18 double precision not null,
c19 float8 not null,
c20 float not null,
c21 float(10) not null,
c22 float(9) not null,
c23 float(53) not null,
c24 float(1) not null
);
insert into num_notnull_t values(n,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24);
insert into num_notnull_t values(n,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24);
select * from num_notnull_t;
-- test char type not null
create table char_notnull_t(
c1 char(10) not null,
c2 char(10),
c3 varchar(20) not null,
c4 varchar(20),
c5 varchar2(20) not null,
c6 varchar2(20),
c7 nchar(20) not null,
c8 nchar(20),
c9 nvarchar2(20) not null,
c10 nvarchar(20),
c11 varchar(20) not null,
c12 varchar(20)
);
insert into char_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11, concat(c11, 'display'));
insert into char_notnull_t values(c1 + 66,
c2 + 88,
concat(c3, 'display'),
concat(c4, 'not display'),
concat(c5, 'display'),
concat(c6, 'not display'),
concat(c7, 'display'),
concat(c8, 'not display'),
concat(c5, ' display'), -- ref after
concat(c10, 'not display'),
concat(c5, ' display'),
concat(c2, ' not display')); -- ref before
select * from char_notnull_t;
-- test time type not null
create table time_notnull_t(
c1 date not null,
c2 time(6) without time zone not null,
c3 time with time zone not null,
c4 time(5) with time zone not null,
c5 timestamp not null,
c6 timestamp without time zone not null,
c7 timestamp(4) without time zone not null,
c8 timestamp with time zone not null,
c9 timestamp(3) with time zone not null,
c10 smalldatetime not null,
c11 interval year not null,
c12 interval month (6) not null,
c13 interval day (5) not null,
c14 interval hour (4) not null,
c15 interval minute (3) not null,
c16 interval second (2) not null,
c17 interval day (2) to second (2) not null,
c18 interval day to hour not null,
c19 interval day to minute not null,
c20 interval hour to minute not null,
c21 interval hour to second not null,
c22 interval minute to second not null,
c23 reltime not null,
c24 abstime not null
);
insert into time_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
c16,c17,c18,c19, c20, c21, c22, c23, c24);
select * from time_notnull_t;
-- test custom types
create type TestEnum as enum ('ok', 'ook','ruok');
create type TestEnum2 as enum ('ok2', 'ook2','ruok2');
create type TestEnum3 as enum ();
create type TestCom as (c1 int, c2 date[], c3 point);
create type TestCom2 as (c1 int, c2 date[], c3 point);
create table enum_set_notnull_t(
c1 TestEnum not null,
c2 TestEnum2 not null,
c3 set('666') not null,
c4 set('hello', 'world') not null
);
insert into enum_set_notnull_t values(c1, c2, c3, c4);
select * from enum_set_notnull_t;
-- test empty enu, other custom types should fail
create table custom_notnull_t(
c0 TestEnum3 not null,
c1 TestEnum not null,
c2 TestEnum2 not null,
c3 TestCom not null,
c4 TestCom2 not null,
c5 int[] not null,
c6 blob[][] not null
);
insert into custom_notnull_t values(c0, c1, c2, c3, c4, c5, c6);
select * from custom_notnull_t;
-- test rest other types not null
create table other_notnull_t(
c1 money not null,
c2 int4range not null,
c3 BLOB not null,
c4 RAW not null,
c5 BYTEA not null,
c6 point not null,
c7 lseg not null,
c8 box not null,
c9 path not null,
c10 polygon not null,
c11 circle not null,
c12 cidr not null,
c13 inet not null,
c14 macaddr not null,
c15 BIT(3) not null,
c16 BIT VARYING(5) not null,
c17 UUID not null,
c18 json not null,
c19 jsonb not null,
c20 int8range not null,
c21 numrange not null,
c22 tsrange not null,
c23 tstzrange not null,
c24 daterange not null,
c25 hll not null,
c26 hll(12, 4) not null,
c27 SET('beijing','shanghai','nanjing','wuhan') not null,
c28 tsvector not null,
c29 tsquery not null,
c30 HASH16 not null,
c31 HASH32 not null,
c32 SET('66') not null
);
insert into other_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
c16,c17,c18,c19, c20, c21, c22, c23, c24, c25, c26,
c27, c28, c29, c30, c31, c32);
insert into other_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
c16,c17,c18,c19, c20, c21, c22, c23, c24, c25, c26,
concat(c27 ,'beijing'), c28, c29, c30, c31, c32);
select * from other_notnull_t;
-- jdbc case
DROP USER IF EXISTS rightref CASCADE;
CREATE USER rightref WITH PASSWORD 'rightref@123';
SET ROLE rightref PASSWORD 'rightref@123';
\! chmod -R 700 @abs_bindir@/../jre
\! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/jdbc_test/gsjdbc400.jar:@abs_builddir@/jdbc_test/insert_right_ref/. InsertRightRefTest localhost @portstring@ rightref rightref rightref@123
RESET ROLE;
DROP USER IF EXISTS rightref CASCADE;
\c postgres
drop database rightref;

View File

@ -0,0 +1,235 @@
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* test Case for insert stament with right value references
*/
public class InsertRightRefTest {
private static final String DEFAULT_DRIVER_NAME = "org.postgresql.Driver";
private static final String DEFAULT_DATABASE = "regression";
private static final String DEFAULT_HOST = "localhost";
private static final String DEFAULT_PORT = "";
private static final String DEFAULT_USER_NAME = "";
private static final String DEFAULT_PASSWORD = "";
private static final int MAX_ROW = 50;
private final Connection con;
private final StringBuilder outputBuffer;
InsertRightRefTest(Connection con) {
this.con = con;
outputBuffer = new StringBuilder();
}
/**
* main programme
*
* @param args args[0]: host
* args[1]: port
* args[2]: database
* args[3]: user name
* args[4]: password
*/
public static void main(String[] args) {
try (Connection con = getConnection(args)) {
new InsertRightRefTest(con).runTestCases();
} catch (Exception exception) {
exception.printStackTrace();
}
}
static Connection getConnection(String[] args) throws SQLException, ClassNotFoundException {
Class.forName(DEFAULT_DRIVER_NAME);
String host = (args != null && args.length > 0) ? args[0] : DEFAULT_HOST;
String port = (args != null && args.length > 1) ? args[1] : DEFAULT_PORT;
String database = (args != null && args.length > 2) ? args[2] : DEFAULT_DATABASE;
String name = (args != null && args.length > 3) ? args[3] : DEFAULT_USER_NAME;
String password = (args != null && args.length > 4) ? args[4] : DEFAULT_PASSWORD;
String url = "jdbc:postgresql://" + host + ":" + port + "/" + database + "?prepareThreshold=0&loggerLevel=off";
return DriverManager.getConnection(url, name, password);
}
void runTestCases() {
// case 1: base test
execute("drop table if exists auto_increment_t;");
execute("create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);");
execute("insert into auto_increment_t values(1, c1, c1, c1);");
String[] batch = {"insert into auto_increment_t values(2, 0, c1, c1);",
"insert into auto_increment_t values(3, 0, c1, c1);",
"insert into auto_increment_t values(4, -1, c1, c1);",
"insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);",
"insert into auto_increment_t values(5, c1, c1, c1);"};
executeBatch(batch);
select("select * from auto_increment_t order by n;", "n", "c1", "c2", "c3");
execute("drop table auto_increment_t;");
execute("create table char_default_t(\n" +
" n serial,\n" +
" c1 char(10) default 'char20',\n" +
" c2 char(10),\n" +
" c3 varchar(10) default 'vc3',\n" +
" c4 varchar(20),\n" +
" c5 varchar2(10) default 'vc210',\n" +
" c6 varchar2(20),\n" +
" c7 nchar(5) default 'c31',\n" +
" c8 nchar(5),\n" +
" c9 nvarchar2(5) default 'c33',\n" +
" c10 nvarchar(5) default 'c34',\n" +
" c11 varchar(20) default concat('hello', ' world'),\n" +
" c12 varchar(20)\n" +
");");
execute("insert into char_default_t values(1);\n" +
"insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);\n" +
"insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);");
select("select * from char_default_t;",
"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12");
execute("drop table if exists char_default_t");
// case 2: upsert
execute("drop table if exists upser;");
execute("create table upser(c1 int, c2 int, c3 int);");
execute("create unique index idx_upser_c1 on upser(c1);");
executeBatch("insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10),\n" +
" (6, 10, 10), (7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);",
"insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100),(9, 100, 100),\n" +
" (10, 100, 100), (11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)\n" +
" on duplicate key update c2 = c1 + c2, c3 = c2 + c3;");
select("select * from upser order by c1;", "c1", "c2", "c3");
executeBatch("truncate upser;",
"insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), \n" +
"(6, 10, 10), (7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);",
"insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100), \n" +
"(8, c1 + 100, 100), (9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100),\n" +
"(12, c1 + 100, 100), (13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)\n" +
"on duplicate key update c2 = c1 + c2, c3 = c2 + c3;");
select("select * from upser order by c1;", "c1", "c2", "c3");
execute("drop table upser;");
// case 3: var & function
execute("drop table if exists with_var;");
execute("drop function if exists with_var_func;");
execute("create table with_var(a int default 999);");
execute("create function with_var_func() return int as\n" +
"declare \n" +
" a int := 666;\n" +
"begin\n" +
" insert into with_var values(a);\n" +
" return a;\n" +
"end;\n" +
"/");
executeBatch("call with_var_func();",
"call with_var_func();",
"call with_var_func();");
select("select * from with_var;", "a");
executeBatch("drop function with_var_func;",
"drop table with_var;");
// case 4: custum types
execute("create table custom_notnull_t(\n" +
" c0 TestEnum3 not null, \n" +
" c1 TestEnum not null,\n" +
" c2 TestEnum2 not null,\n" +
" c3 TestCom not null,\n" +
" c4 TestCom2 not null,\n" +
" c5 int[] not null,\n" +
" c6 blob[][] not null\n" +
");");
execute("insert into custom_notnull_t values(c0, c1, c2, c3, c4, c5, c6);");
select("select * from custom_notnull_t;", "c0", "c1", "c2", "c3", "c4", "c5", "c6");
// case 5: set, enum
execute("create table enum_set_notnull_t(\n" +
" c1 TestEnum not null,\n" +
" c2 TestEnum2 not null,\n" +
" c3 set('666') not null,\n" +
" c4 set('hello', 'world') not null\n" +
");\n" +
"insert into enum_set_notnull_t values(c1, c2, c3, c4);");
select("select * from enum_set_notnull_t;", "c1", "c2", "c3", "c4");
}
void select(String sql, String... fields) {
System.out.println(sql);
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
int[] maxWidths = new int[fields.length];
for (int i = 0; i < fields.length; i++) {
maxWidths[i] = fields[i].length();
}
int cnt = 0;
List<String[]> data = new ArrayList<>();
while (cnt++ < MAX_ROW && rs.next()) {
String[] row = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
row[i] = rs.getString(fields[i]);
if (row[i] == null) {
row[i] = "?_?";
}
if (row[i].length() > maxWidths[i]) {
maxWidths[i] = row[i].length();
}
}
data.add(row);
}
printRow(maxWidths, fields);
printSeparator(maxWidths);
for (String[] row : data) {
printRow(maxWidths, row);
}
if (data.size() == 1) {
System.out.println("(1 row)");
} else {
System.out.println("(" + data.size() + " rows)");
}
System.out.println();
} catch (SQLException exception) {
System.err.println(exception.getMessage());
}
}
void execute(String sql) {
System.out.println(sql);
try (Statement stmt = con.createStatement()) {
stmt.execute(sql);
} catch (SQLException exception) {
System.err.println(exception.getMessage());
}
}
void executeBatch(String... sqls) {
try (Statement stmt = con.createStatement()) {
for (String sql : sqls) {
stmt.addBatch(sql);
System.out.println(sql);
}
stmt.executeBatch();
} catch (SQLException exception) {
System.err.println(exception.getMessage());
}
}
void printRow(int[] maxWidths, String[] values) {
outputBuffer.append("|");
for (int i = 0; i < maxWidths.length; i++) {
outputBuffer.append(String.format(" %-" + maxWidths[i] + "s |", values[i]));
}
System.out.println(outputBuffer);
outputBuffer.delete(0, outputBuffer.length());
}
void printSeparator(int[] maxWidths) {
for (int maxWidth : maxWidths) {
String format = String.format("+-%-" + maxWidth + "s-", '-').replaceAll(" ", "-");
outputBuffer.append(format);
}
outputBuffer.append("+");
System.out.println(outputBuffer);
outputBuffer.delete(0, outputBuffer.length());
}
}

View File

@ -0,0 +1,697 @@
create database rightref with dbcompatibility 'B';
\c rightref
-- test fields order
create table test_order_t(n1 int default 100, n2 int default 100, s int);
insert into test_order_t values(1000, 1000, n1 + n2);
insert into test_order_t(s, n1, n2) values(n1 + n2, 300, 300);
select * from test_order_t;
n1 | n2 | s
------+------+------
1000 | 1000 | 2000
300 | 300 | 200
(2 rows)
drop table test_order_t;
-- test non-idempotent function
create table non_idempotent_t(c1 float, c2 float, c3 float);
insert into non_idempotent_t values(random(), c1, c1);
select c1 = c2 as f1, c1 = c3 as f2 from non_idempotent_t;
f1 | f2
----+----
t | t
(1 row)
drop table non_idempotent_t;
-- test auto increment
create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);
NOTICE: CREATE TABLE will create implicit sequence "auto_increment_t_c1_seq" for serial column "auto_increment_t.c1"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "auto_increment_t_pkey" for table "auto_increment_t"
insert into auto_increment_t values(1, c1, c1, c1);
insert into auto_increment_t values(2, 0, c1, c1);
insert into auto_increment_t values(3, 0, c1, c1);
insert into auto_increment_t values(4, -1, c1, c1);
insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);
insert into auto_increment_t values(5, c1, c1, c1);
select * from auto_increment_t order by n;
n | c1 | c2 | c3
---+------+----+----
1 | 1 | 0 | 0
2 | 2 | 0 | 0
3 | 3 | 0 | 0
4 | -1 | -1 | -1
5 | 1000 | 0 | 0
5 | 1001 | 0 | 0
(6 rows)
drop table auto_increment_t;
-- test series
create table test_series_t(c1 int, c2 int, c3 int);
insert into test_series_t values(c2 + 10, generate_series(1, 10), c2 * 2);
select * from test_series_t;
c1 | c2 | c3
----+----+----
| 1 | 2
| 2 | 4
| 3 | 6
| 4 | 8
| 5 | 10
| 6 | 12
| 7 | 14
| 8 | 16
| 9 | 18
| 10 | 20
(10 rows)
drop table test_series_t;
-- test upsert
-- 1
create table upser(c1 int, c2 int, c3 int);
create unique index idx_upser_c1 on upser(c1);
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10), (7, 10, 10),
(8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100), (9, 100, 100), (10, 100, 100),
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
on duplicate key update c2 = 2000, c3 = 2000;
select * from upser order by c1;
c1 | c2 | c3
----+------+------
1 | 10 | 10
2 | 10 | 10
3 | 10 | 10
4 | 10 | 10
5 | 2000 | 2000
6 | 2000 | 2000
7 | 2000 | 2000
8 | 2000 | 2000
9 | 2000 | 2000
10 | 2000 | 2000
11 | 100 | 100
12 | 100 | 100
13 | 100 | 100
14 | 100 | 100
15 | 100 | 100
(15 rows)
-- 2
truncate upser;
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10), (7, 10, 10),
(8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100), (9, 100, 100), (10, 100, 100),
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
select * from upser order by c1;
c1 | c2 | c3
----+-----+-----
1 | 10 | 10
2 | 10 | 10
3 | 10 | 10
4 | 10 | 10
5 | 15 | 25
6 | 16 | 26
7 | 17 | 27
8 | 18 | 28
9 | 19 | 29
10 | 20 | 30
11 | 100 | 100
12 | 100 | 100
13 | 100 | 100
14 | 100 | 100
15 | 100 | 100
(15 rows)
-- 3
truncate upser;
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10),
(7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100), (8, c1 + 100, 100),
(9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100), (12, c1 + 100, 100),
(13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
select * from upser order by c1;
c1 | c2 | c3
----+-----+-----
1 | 10 | 10
2 | 10 | 10
3 | 10 | 10
4 | 10 | 10
5 | 15 | 25
6 | 16 | 26
7 | 17 | 27
8 | 18 | 28
9 | 19 | 29
10 | 20 | 30
11 | 111 | 100
12 | 112 | 100
13 | 113 | 100
14 | 114 | 100
15 | 115 | 130
(15 rows)
drop table upser;
-- test var
create table with_var(a int default 999);
create function with_var_func() return int as
declare
a int := 666;
begin
insert into with_var values(a);
return a;
end;
/
call with_var_func();
with_var_func
---------------
666
(1 row)
select * from with_var;
a
-----
666
(1 row)
drop function with_var_func;
drop table with_var;
-- test num type
create table num_default_t (
n serial,
c1 int default 1,
c2 int,
c3 tinyint default 3,
c4 tinyint,
c5 smallint default 5,
c6 smallint,
c7 integer default 7,
c8 integer,
c9 binary_integer default 9,
c10 bigint default 10,
c11 bigint,
c12 boolean default true,
c13 boolean,
c14 numeric default 14.,
c15 numeric(10, 3) default 15.,
c16 decimal default 16,
c17 decimal(10, 2) default 17,
c18 double precision default 18,
c19 float8,
c20 float default 100 / 10,
c21 float default 20 * (100 + 2) - 3,
c22 float default random(),
c23 float default random() * 100,
c24 float
);
NOTICE: CREATE TABLE will create implicit sequence "num_default_t_n_seq" for serial column "num_default_t.n"
insert into num_default_t values(1);
insert into num_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
c21, c22, c23, c24);
insert into num_default_t values(3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
c21, c22, c23, c20);
insert into num_default_t(n, c23, c24) values(4, default, c23);
select 3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21
from num_default_t;
?column? | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21
----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+--------+-----+-------+-----+-----+-----+------
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
(4 rows)
select (c23 = c24) as equal from num_default_t where n = 4;
equal
-------
t
(1 row)
select (c22 is null) as c22_is_null, (c23 is null) as c23_is_null from num_default_t where n = 2 or n = 3;
c22_is_null | c23_is_null
-------------+-------------
t | t
t | t
(2 rows)
select (c22 is not null) as c22_is_not_null, (c23 is not null) as c23_is_not_null from num_default_t where n = 1;
c22_is_not_null | c23_is_not_null
-----------------+-----------------
t | t
(1 row)
-- test char type
create table char_default_t(
n serial,
c1 char(10) default 'char20',
c2 char(10),
c3 varchar(10) default 'vc3',
c4 varchar(20),
c5 varchar2(10) default 'vc210',
c6 varchar2(20),
c7 nchar(5) default 'c31',
c8 nchar(5),
c9 nvarchar2(5) default 'c33',
c10 nvarchar(5) default 'c34',
c11 varchar(20) default concat('hello', ' world'),
c12 varchar(20)
);
NOTICE: CREATE TABLE will create implicit sequence "char_default_t_n_seq" for serial column "char_default_t.n"
insert into char_default_t values(1);
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
select * from char_default_t;
n | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12
---+------------+----+-----+---------+-------+----+-------+----+-----+-----+-------------+-------------
1 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | hello world |
2 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | |
3 | char20 | | vc3 | vc3 vc4 | vc210 | | c31 | | c33 | c34 | hello world | hello world
(3 rows)
-- test time type
create table time_default_t(
n serial,
c1 timestamp default '2022-12-12 22:22:22',
c2 timestamp,
c3 date default '2022-12-12',
c4 date,
c5 time default '22:22:22',
c6 date default current_date,
c7 date,
c8 timestamp default current_timestamp,
c9 timestamp,
c10 time default current_time,
c11 time,
c12 time with time zone default current_time,
c13 time
);
NOTICE: CREATE TABLE will create implicit sequence "time_default_t_n_seq" for serial column "time_default_t.n"
insert into time_default_t values(1);
insert into time_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
insert into time_default_t values(3, default, c1, default, c3, default, default, c6,
default, c8, default, c10, default, c12);
select n, c1, c2, c3, c4, c5 from time_default_t;
n | c1 | c2 | c3 | c4 | c5
---+--------------------------+--------------------------+------------+------------+----------
1 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
2 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
3 | Mon Dec 12 22:22:22 2022 | Mon Dec 12 22:22:22 2022 | 12-12-2022 | 12-12-2022 | 22:22:22
(3 rows)
select (c6 is not null) as c6_is_not_null,
(c8 is not null) as c8_is_not_null,
(c10 is not null) as c10_is_not_null,
(c12 is not null) as c12_is_not_null
from time_default_t where n = 1 or n = 3;
c6_is_not_null | c8_is_not_null | c10_is_not_null | c12_is_not_null
----------------+----------------+-----------------+-----------------
t | t | t | t
t | t | t | t
(2 rows)
select (c6 is not null) c6_is_not_null,
(c8 is null) as c8_is_null,
(c10 is null) as c10_is_null,
(c12 is null) as c12_is_null
from time_default_t where n = 2;
c6_is_not_null | c8_is_null | c10_is_null | c12_is_null
----------------+------------+-------------+-------------
t | t | t | t
(1 row)
select (c1=c2) as c1c2,
(c3=c4) as c3c4,
(c6=c7) as c6c7,
(c8=c9) as c8c9,
(c10=c11) as c10c11,
(c12=c13) as c12c13
from time_default_t where n = 3;
c1c2 | c3c4 | c6c7 | c8c9 | c10c11 | c12c13
------+------+------+------+--------+--------
t | t | t | t | t | t
(1 row)
-- test num type not null
create table num_notnull_t (
n serial not null,
c1 int not null,
c2 int not null,
c3 tinyint not null,
c4 tinyint not null,
c5 smallint not null,
c6 smallint not null,
c7 integer not null,
c8 integer not null,
c9 binary_integer not null,
c10 bigint not null,
c11 bigint not null,
c12 boolean not null,
c13 boolean not null,
c14 numeric not null,
c15 numeric(10, 3) not null,
c16 decimal not null,
c17 dec(21, 6) not null,
c18 double precision not null,
c19 float8 not null,
c20 float not null,
c21 float(10) not null,
c22 float(9) not null,
c23 float(53) not null,
c24 float(1) not null
);
NOTICE: CREATE TABLE will create implicit sequence "num_notnull_t_n_seq" for serial column "num_notnull_t.n"
insert into num_notnull_t values(n,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24);
insert into num_notnull_t values(n,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24);
select * from num_notnull_t;
n | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21 | c22 | c23 | c24
---+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | f | f | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | f | f | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
(2 rows)
-- test char type not null
create table char_notnull_t(
c1 char(10) not null,
c2 char(10),
c3 varchar(20) not null,
c4 varchar(20),
c5 varchar2(20) not null,
c6 varchar2(20),
c7 nchar(20) not null,
c8 nchar(20),
c9 nvarchar2(20) not null,
c10 nvarchar(20),
c11 varchar(20) not null,
c12 varchar(20)
);
insert into char_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11, concat(c11, 'display'));
insert into char_notnull_t values(c1 + 66,
c2 + 88,
concat(c3, 'display'),
concat(c4, 'not display'),
concat(c5, 'display'),
concat(c6, 'not display'),
concat(c7, 'display'),
concat(c8, 'not display'),
concat(c5, ' display'), -- ref after
concat(c10, 'not display'),
concat(c5, ' display'),
concat(c2, ' not display')); -- ref before
select * from char_notnull_t;
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12
------------+----+---------+----+---------+----+----------------------+----+-----------------+-----+-----------------+---------
| | | | | | | | | | | display
66 | | display | | display | | display | | display display | | display display |
(2 rows)
-- test time type not null
create table time_notnull_t(
c1 date not null,
c2 time(6) without time zone not null,
c3 time with time zone not null,
c4 time(5) with time zone not null,
c5 timestamp not null,
c6 timestamp without time zone not null,
c7 timestamp(4) without time zone not null,
c8 timestamp with time zone not null,
c9 timestamp(3) with time zone not null,
c10 smalldatetime not null,
c11 interval year not null,
c12 interval month (6) not null,
c13 interval day (5) not null,
c14 interval hour (4) not null,
c15 interval minute (3) not null,
c16 interval second (2) not null,
c17 interval day (2) to second (2) not null,
c18 interval day to hour not null,
c19 interval day to minute not null,
c20 interval hour to minute not null,
c21 interval hour to second not null,
c22 interval minute to second not null,
c23 reltime not null,
c24 abstime not null
);
insert into time_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
c16,c17,c18,c19, c20, c21, c22, c23, c24);
select * from time_notnull_t;
--?.*
--?.*
--?01-01-1970 | 00:00:00 | 00:00:00-08 | 00:00:00-08 | .* | .* | .* | .* | .* | Thu Jan 01 00:00:00 1970 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | .*
(1 row)
-- test custom types
create type TestEnum as enum ('ok', 'ook','ruok');
create type TestEnum2 as enum ('ok2', 'ook2','ruok2');
create type TestEnum3 as enum ();
create type TestCom as (c1 int, c2 date[], c3 point);
create type TestCom2 as (c1 int, c2 date[], c3 point);
create table enum_set_notnull_t(
c1 TestEnum not null,
c2 TestEnum2 not null,
c3 set('666') not null,
c4 set('hello', 'world') not null
);
NOTICE: CREATE TABLE will create implicit set "enum_set_notnull_t_c3_set" for column "enum_set_notnull_t.c3"
NOTICE: CREATE TABLE will create implicit set "enum_set_notnull_t_c4_set" for column "enum_set_notnull_t.c4"
insert into enum_set_notnull_t values(c1, c2, c3, c4);
select * from enum_set_notnull_t;
c1 | c2 | c3 | c4
----+-----+----+----
ok | ok2 | |
(1 row)
-- test empty enu, other custom types should fail
create table custom_notnull_t(
c0 TestEnum3 not null,
c1 TestEnum not null,
c2 TestEnum2 not null,
c3 TestCom not null,
c4 TestCom2 not null,
c5 int[] not null,
c6 blob[][] not null
);
insert into custom_notnull_t values(c0, c1, c2, c3, c4, c5, c6);
ERROR: null value in column "c0" violates not-null constraint
DETAIL: Failing row contains (null, ok, ok2, null, null, null, null).
select * from custom_notnull_t;
c0 | c1 | c2 | c3 | c4 | c5 | c6
----+----+----+----+----+----+----
(0 rows)
-- test rest other types not null
create table other_notnull_t(
c1 money not null,
c2 int4range not null,
c3 BLOB not null,
c4 RAW not null,
c5 BYTEA not null,
c6 point not null,
c7 lseg not null,
c8 box not null,
c9 path not null,
c10 polygon not null,
c11 circle not null,
c12 cidr not null,
c13 inet not null,
c14 macaddr not null,
c15 BIT(3) not null,
c16 BIT VARYING(5) not null,
c17 UUID not null,
c18 json not null,
c19 jsonb not null,
c20 int8range not null,
c21 numrange not null,
c22 tsrange not null,
c23 tstzrange not null,
c24 daterange not null,
c25 hll not null,
c26 hll(12, 4) not null,
c27 SET('beijing','shanghai','nanjing','wuhan') not null,
c28 tsvector not null,
c29 tsquery not null,
c30 HASH16 not null,
c31 HASH32 not null,
c32 SET('66') not null
);
NOTICE: CREATE TABLE will create implicit set "other_notnull_t_c27_set" for column "other_notnull_t.c27"
NOTICE: CREATE TABLE will create implicit set "other_notnull_t_c32_set" for column "other_notnull_t.c32"
insert into other_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
c16,c17,c18,c19, c20, c21, c22, c23, c24, c25, c26,
c27, c28, c29, c30, c31, c32);
insert into other_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
c16,c17,c18,c19, c20, c21, c22, c23, c24, c25, c26,
concat(c27 ,'beijing'), c28, c29, c30, c31, c32);
select * from other_notnull_t;
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21 | c22 | c23 | c24 | c25 | c26 | c27 | c28 | c29 | c30 | c31 | c32
-------+-------+----+----+----+-------+---------------+-------------+---------+---------+-----------+------------+---------+-------------------+-----+-----+--------------------------------------+------+------+-------+-------+-------+-------+-------+-----+-----+---------+-----+-----+------------------+----------------------------------+-----
$0.00 | empty | | | \x | (0,0) | [(0,0),(0,0)] | (0,0),(0,0) | ((0,0)) | ((0,0)) | <(0,0),0> | 0.0.0.0/32 | 0.0.0.0 | 00:00:00:00:00:00 | | | 00000000-0000-0000-0000-000000000000 | null | null | empty | empty | empty | empty | empty | \x | \x | | | | 0000000000000000 | 00000000000000000000000000000000 |
$0.00 | empty | | | \x | (0,0) | [(0,0),(0,0)] | (0,0),(0,0) | ((0,0)) | ((0,0)) | <(0,0),0> | 0.0.0.0/32 | 0.0.0.0 | 00:00:00:00:00:00 | | | 00000000-0000-0000-0000-000000000000 | null | null | empty | empty | empty | empty | empty | \x | \x | beijing | | | 0000000000000000 | 00000000000000000000000000000000 |
(2 rows)
-- jdbc case
DROP USER IF EXISTS rightref CASCADE;
NOTICE: role "rightref" does not exist, skipping
CREATE USER rightref WITH PASSWORD 'rightref@123';
SET ROLE rightref PASSWORD 'rightref@123';
--?.*
--?.*
drop table if exists auto_increment_t;
create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);
insert into auto_increment_t values(1, c1, c1, c1);
insert into auto_increment_t values(2, 0, c1, c1);
insert into auto_increment_t values(3, 0, c1, c1);
insert into auto_increment_t values(4, -1, c1, c1);
insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);
insert into auto_increment_t values(5, c1, c1, c1);
select * from auto_increment_t order by n;
| n | c1 | c2 | c3 |
+---+------+----+----+
| 1 | 1 | 0 | 0 |
| 2 | 2 | 0 | 0 |
| 3 | 3 | 0 | 0 |
| 4 | -1 | -1 | -1 |
| 5 | 1000 | 0 | 0 |
| 5 | 1001 | 0 | 0 |
(6 rows)
drop table auto_increment_t;
create table char_default_t(
n serial,
c1 char(10) default 'char20',
c2 char(10),
c3 varchar(10) default 'vc3',
c4 varchar(20),
c5 varchar2(10) default 'vc210',
c6 varchar2(20),
c7 nchar(5) default 'c31',
c8 nchar(5),
c9 nvarchar2(5) default 'c33',
c10 nvarchar(5) default 'c34',
c11 varchar(20) default concat('hello', ' world'),
c12 varchar(20)
);
insert into char_default_t values(1);
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
select * from char_default_t;
| c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 |
+------------+-----+-----+---------+-------+-----+-------+-----+-----+-----+-------------+-------------+
| char20 | ?_? | vc3 | ?_? | vc210 | ?_? | c31 | ?_? | c33 | c34 | hello world | ?_? |
| char20 | ?_? | vc3 | ?_? | vc210 | ?_? | c31 | ?_? | c33 | c34 | ?_? | ?_? |
| char20 | ?_? | vc3 | vc3 vc4 | vc210 | ?_? | c31 | ?_? | c33 | c34 | hello world | hello world |
(3 rows)
drop table if exists char_default_t
drop table if exists upser;
create table upser(c1 int, c2 int, c3 int);
create unique index idx_upser_c1 on upser(c1);
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10),
(6, 10, 10), (7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100),(9, 100, 100),
(10, 100, 100), (11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
select * from upser order by c1;
| c1 | c2 | c3 |
+----+-----+-----+
| 1 | 10 | 10 |
| 2 | 10 | 10 |
| 3 | 10 | 10 |
| 4 | 10 | 10 |
| 5 | 15 | 25 |
| 6 | 16 | 26 |
| 7 | 17 | 27 |
| 8 | 18 | 28 |
| 9 | 19 | 29 |
| 10 | 20 | 30 |
| 11 | 100 | 100 |
| 12 | 100 | 100 |
| 13 | 100 | 100 |
| 14 | 100 | 100 |
| 15 | 100 | 100 |
(15 rows)
truncate upser;
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10),
(6, 10, 10), (7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100),
(8, c1 + 100, 100), (9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100),
(12, c1 + 100, 100), (13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
select * from upser order by c1;
| c1 | c2 | c3 |
+----+-----+-----+
| 1 | 10 | 10 |
| 2 | 10 | 10 |
| 3 | 10 | 10 |
| 4 | 10 | 10 |
| 5 | 15 | 25 |
| 6 | 16 | 26 |
| 7 | 17 | 27 |
| 8 | 18 | 28 |
| 9 | 19 | 29 |
| 10 | 20 | 30 |
| 11 | 111 | 100 |
| 12 | 112 | 100 |
| 13 | 113 | 100 |
| 14 | 114 | 100 |
| 15 | 115 | 130 |
(15 rows)
drop table upser;
drop table if exists with_var;
drop function if exists with_var_func;
create table with_var(a int default 999);
create function with_var_func() return int as
declare
a int := 666;
begin
insert into with_var values(a);
return a;
end;
/
call with_var_func();
call with_var_func();
call with_var_func();
select * from with_var;
| a |
+-----+
| 666 |
| 666 |
| 666 |
(3 rows)
drop function with_var_func;
drop table with_var;
create table custom_notnull_t(
c0 TestEnum3 not null,
c1 TestEnum not null,
c2 TestEnum2 not null,
c3 TestCom not null,
c4 TestCom2 not null,
c5 int[] not null,
c6 blob[][] not null
);
insert into custom_notnull_t values(c0, c1, c2, c3, c4, c5, c6);
--?.*ERROR: null value in column "c0" violates not-null constraint
Detail: Failing row contains (null, ok, ok2, null, null, null, null).
select * from custom_notnull_t;
| c0 | c1 | c2 | c3 | c4 | c5 | c6 |
+----+----+----+----+----+----+----+
(0 rows)
create table enum_set_notnull_t(
c1 TestEnum not null,
c2 TestEnum2 not null,
c3 set('666') not null,
c4 set('hello', 'world') not null
);
insert into enum_set_notnull_t values(c1, c2, c3, c4);
select * from enum_set_notnull_t;
| c1 | c2 | c3 | c4 |
+----+-----+----+----+
| ok | ok2 | | |
(1 row)
RESET ROLE;
DROP USER IF EXISTS rightref CASCADE;
\c postgres
drop database rightref;

View File

@ -1,202 +0,0 @@
create database rightref with dbcompatibility 'B';
\c rightref
-- test fields order
create table test_order_t(n1 int default 100, n2 int default 100, s int);
insert into test_order_t values(1000, 1000, n1 + n2);
insert into test_order_t(s, n1, n2) values(n1 + n2, 300, 300);
select * from test_order_t;
drop table test_order_t;
-- test non-idempotent function
create table non_idempotent_t(c1 float, c2 float, c3 float);
insert into non_idempotent_t values(random(), c1, c1);
select c1 = c2 as f1, c1 = c3 as f2 from non_idempotent_t;
drop table non_idempotent_t;
-- test auto increment
create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);
insert into auto_increment_t values(1, c1, c1, c1);
insert into auto_increment_t values(2, 0, c1, c1);
insert into auto_increment_t values(3, 0, c1, c1);
insert into auto_increment_t values(4, -1, c1, c1);
insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);
insert into auto_increment_t values(5, c1, c1, c1);
select * from auto_increment_t order by n;
drop table auto_increment_t;
-- test series
create table test_series_t(c1 int, c2 int, c3 int);
insert into test_series_t values(c2 + 10, generate_series(1, 10), c2 * 2);
select * from test_series_t;
drop table test_series_t;
-- test upsert
-- 1
create table upser(c1 int, c2 int, c3 int);
create unique index idx_upser_c1 on upser(c1);
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10), (7, 10, 10),
(8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100), (9, 100, 100), (10, 100, 100),
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
on duplicate key update c2 = 2000, c3 = 2000;
select * from upser order by c1;
-- 2
truncate upser;
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10), (7, 10, 10),
(8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100), (9, 100, 100), (10, 100, 100),
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
select * from upser order by c1;
-- 3
truncate upser;
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10),
(7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100), (8, c1 + 100, 100),
(9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100), (12, c1 + 100, 100),
(13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
select * from upser order by c1;
drop table upser;
-- test var
create table with_var(a int default 999);
create function with_var_func() return int as
declare
a int := 666;
begin
insert into with_var values(a);
return a;
end;
/
call with_var_func();
select * from with_var;
drop function with_var_func;
drop table with_var;
-- test num type
create table num_default_t (
n serial,
c1 int default 1,
c2 int,
c3 tinyint default 3,
c4 tinyint,
c5 smallint default 5,
c6 smallint,
c7 integer default 7,
c8 integer,
c9 binary_integer default 9,
c10 bigint default 10,
c11 bigint,
c12 boolean default true,
c13 boolean,
c14 numeric default 14.,
c15 numeric(10, 3) default 15.,
c16 decimal default 16,
c17 decimal(10, 2) default 17,
c18 double precision default 18,
c19 float8,
c20 float default 100 / 10,
c21 float default 20 * (100 + 2) - 3,
c22 float default random(),
c23 float default random() * 100,
c24 float
);
insert into num_default_t values(1);
insert into num_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
c21, c22, c23, c24);
insert into num_default_t values(3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
c21, c22, c23, c20);
insert into num_default_t(n, c23, c24) values(4, default, c23);
select 3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21
from num_default_t;
select (c23 = c24) as equal from num_default_t where n = 4;
select (c22 is null) as c22_is_null, (c23 is null) as c23_is_null from num_default_t where n = 2 or n = 3;
select (c22 is not null) as c22_is_not_null, (c23 is not null) as c23_is_not_null from num_default_t where n = 1;
-- test char type
create table char_default_t(
n serial,
c1 char(10) default 'char20',
c2 char(10),
c3 varchar(10) default 'vc3',
c4 varchar(20),
c5 varchar2(10) default 'vc210',
c6 varchar2(20),
c7 nchar(5) default 'c31',
c8 nchar(5),
c9 nvarchar2(5) default 'c33',
c10 nvarchar(5) default 'c34',
c11 varchar(20) default concat('hello', ' world'),
c12 varchar(20)
);
insert into char_default_t values(1);
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
select * from char_default_t;
-- test time type
create table time_default_t(
n serial,
c1 timestamp default '2022-12-12 22:22:22',
c2 timestamp,
c3 date default '2022-12-12',
c4 date,
c5 time default '22:22:22',
c6 date default current_date,
c7 date,
c8 timestamp default current_timestamp,
c9 timestamp,
c10 time default current_time,
c11 time,
c12 time with time zone default current_time,
c13 time
);
insert into time_default_t values(1);
insert into time_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
insert into time_default_t values(3, default, c1, default, c3, default, default, c6,
default, c8, default, c10, default, c12);
select n, c1, c2, c3, c4, c5 from time_default_t;
select (c6 is not null) as c6_is_not_null,
(c8 is not null) as c8_is_not_null,
(c10 is not null) as c10_is_not_null,
(c12 is not null) as c12_is_not_null
from time_default_t where n = 1 or n = 3;
select (c6 is not null) c6_is_not_null,
(c8 is null) as c8_is_null,
(c10 is null) as c10_is_null,
(c12 is null) as c12_is_null
from time_default_t where n = 2;
select (c1=c2) as c1c2,
(c3=c4) as c3c4,
(c6=c7) as c6c7,
(c8=c9) as c8c9,
(c10=c11) as c10c11,
(c12=c13) as c12c13
from time_default_t where n = 3;
\c postgres
drop database rightref;